home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / p / pcrte224.zip / SOURCE.ZIP / ATALK.INC < prev    next >
Text File  |  1992-06-09  |  24KB  |  665 lines

  1. ;;*****************************************************************************
  2. ;;                         atalk.inc           atalk.inc
  3. ;;*****************************************************************************
  4. ;;
  5. ;;  Copyright (C) 1989 Northwestern University, Vance Morrison
  6. ;;
  7. ;;
  8. ;; Permission to view, compile, and modify for LOCAL (intra-organization) 
  9. ;; USE ONLY is hereby granted, provided that this copyright and permission 
  10. ;; notice appear on all copies.  Any other use by permission only.
  11. ;;
  12. ;; Northwestern University makes no representations about the suitability 
  13. ;; of this software for any purpose.  It is provided "as is" without expressed 
  14. ;; or implied warranty.  See the copywrite notice file for complete details.
  15. ;;
  16. ;;*****************************************************************************
  17. ;;
  18. ;;  atalk.inc contains the DL_IP interface for the Appletalk protocols.  
  19. ;;  That is this module contains the code that wraps IP packets up into
  20. ;;  appletalk packets before sending them out, and unencapsulates incomming
  21. ;;  IP packets.  As far has IP is concerned this is just a DL_IP interface
  22. ;;
  23. ;;  This module assumes that there is a Apple localtalk card (or Flashcard) 
  24. ;;  installed in the computer and the Appletalk drivers have been loaded 
  25. ;;  (atalk.sys or atalk.exe).  This module does not implement appletalk, 
  26. ;;  it just calls the driver with wrapped up IP packets.
  27. ;;
  28. ;;   ATP_DECLARE name, interupt, task
  29. ;;   ATP_DEFINE name, ip_address, ip_mask
  30. ;;   ATP_DL_IP_R_READ name, code_label
  31. ;;   ATP_DL_IP_R_CONT_in_BX_CX_ES_const_BX_CX_DX_BP_SI_DI_ES name, ok
  32. ;;   ATP_DL_IP_RETURN name
  33. ;;   ATP_DL_IP_W_ACCESS_in_CX_out_DI_ES_const_CX_BP name, fail
  34. ;;   ATP_DL_IP_W_WRITE_in_AX_CX_const_BP name, broadcast
  35. ;;   ATP_DL_IP_IS_BROADCAST_in_BX_ES_const_AX_BX_CX_DX_BP_DI_ES name
  36. ;;   ATP_DL_IP_COPY_in_CX_SI_DI_ES_out_SI_DI_const_BX_BP_ES name
  37. ;;
  38. ;;  Variables Provided by this module (READ ONLY!!!!)
  39. ;;      
  40. ;;      atp_&name&_declared         1 if this object has been declared
  41. ;;      dl_ip_&name&_ip             the IP address
  42. ;;      dl_ip_&name&_mask           the network mask
  43. ;;      dl_ip_&name&_net            the network (IP addr bitwize AND ip_mask)
  44. ;;      dl_ip_&name&_broad          the network broadcast address
  45. ;;      dl_ip_&name&_flags          A word exclusively for IP use
  46. ;;      dl_ip_&name&_metric         The interface metric (for routing use)
  47. ;;      dl_ip_&name&_mtu            the Maximum transmission unit (packet size)
  48. ;;
  49. ;;*****************************************************************************
  50.  
  51.  
  52. ;;*****************************************************************************
  53. ;; data storage needed by this module
  54.  
  55.     include at.inc          ;; FLASHCARD interface defs
  56.  
  57. atp_w_q_entry STRUC
  58.     atp_q_wparam    DDPParams <>        ;; this MUST be first
  59.     atp_q_end       DW ?
  60. atp_w_q_entry ENDS
  61.  
  62. atp_arp_entry STRUC
  63.     atp_NBP_lookup    NBPparams <>      ;; THIS MUST BE FIRST
  64.     atp_NBT_lookup    NBPTuple <>
  65.     atp_ip_lookup     db 4 DUP (0)      ;; IP address to look up
  66.     atp_buff_lookup   db 64 DUP (0)     ;; buffer to hold NBP name to look up
  67. atp_arp_entry ENDS
  68.  
  69. ATP_R_QUEUE_SIZE = 3                    ;; size of the read queue
  70.  
  71. atp_r_q_entry STRUC
  72.     atp_q_rparam     DDPParams <>       ;; this must be first
  73.     atp_q_rbuff      DB 590 DUP (0)     ;; stuff needed for read
  74. atp_r_q_entry ENDS
  75.  
  76. atp_data    STRUC
  77.     atp_DDP_param_in  DDPParams <>
  78.     atp_Info_param    InfoParams <>     ;; stuff needed for initilization
  79.     atp_NBP_myip      NBPparams <>
  80.     atp_NBTE_myip     NBPTabEntry <>
  81.     atp_r_queue       DW ?
  82. atp_data     ENDS
  83.  
  84.  
  85. ;;*****************************************************************************
  86. ;; ATP_DECLARE name, interupt, task
  87. ;;    ATP_DECLARE declares all the external defintions for the ATP object
  88. ;;
  89. ATP_DECLARE MACRO name, interupt, task, wqueuesize, wbuffsize, num_zones
  90.     .errb <wbuffsize>
  91.  
  92.     atp_&name&_declared = 1
  93.     atp_&name&_interupt = interupt
  94.     atp_&name&_task = task
  95.     atp_&name&_wqueuesize = wqueuesize
  96.     atp_&name&_wbuffsize  = wbuffsize 
  97.     atp_&name&_wbuff      = name*100+1 
  98.     atp_&name&_wqueue     = name*100+2 
  99.     atp_&name&_arptab     = name*100+3
  100.     ifb <num_zones>
  101.         atp_&name&_nzones  = 3
  102.     else
  103.         atp_&name&_nzones  = num_zones
  104.     endif
  105.     atp_&name&_zbuff_len  =  atp_&name&_nzones*16+5
  106.     dl_ip_&name&_mtu      = 578
  107.  
  108.     .DATA
  109.     global dl_ip_&name&_ip:dword
  110.     global dl_ip_&name&_mask:dword
  111.     global dl_ip_&name&_net:dword
  112.     global dl_ip_&name&_broad:dword
  113.     global dl_ip_&name&_flags:word
  114.     global dl_ip_&name&_metric:word
  115.     global atp_&name&_data:atp_data 
  116.     global atp_&name&_read:word 
  117.     global atp_&name&_arps:atp_arp_entry 
  118.     global atp_&name&_wbuffer:byte
  119.     global atp_&name&_rqueue:atp_r_q_entry
  120.     dl_ip_&name&_haddr    = (atp_&name&_data.atp_Info_param.inf_network)
  121.     .CODE
  122.     global atp_&name&_continue:near 
  123.     global atp_&name&_real_define:near
  124.  
  125.     BUFF_DECLARE %atp_&name&_wbuff, wbuffsize, atp_&name&_wbuffer
  126.     QUEUE_DECLARE %atp_&name&_wqueue, wqueuesize, %(size atp_w_q_entry)
  127.     ARP_TAB_DECLARE %atp_&name&_arptab
  128. ENDM
  129.  
  130.  
  131. ;;*****************************************************************************
  132. ;;   ATP_DEFINE name, ip_address, ip_mask, fail
  133. ;;   
  134. ATP_DEFINE MACRO name, ip_address, ip_mask, zones, fail
  135.  
  136. ifdef atp_&name&_declared 
  137.  
  138.     mov AX, word ptr ip_address                 ;; copy over params
  139.     mov BX, 0FFFFH                              ;; Force our assumtion 
  140.     mov word ptr dl_ip_&name&_ip, AX
  141.     mov word ptr dl_ip_&name&_net, AX
  142.     mov word ptr dl_ip_&name&_broad, AX
  143.     mov word ptr dl_ip_&name&_mask, BX
  144.  
  145.     mov AX, word ptr ip_address+2
  146.     mov BX, word ptr ip_mask+2
  147.     mov word ptr dl_ip_&name&_ip+2, AX
  148.     mov word ptr dl_ip_&name&_mask+2, BX
  149.     and AX, BX
  150.     mov word ptr dl_ip_&name&_net+2, AX
  151.     not BX
  152.     or AX, BX
  153.     mov word ptr dl_ip_&name&_broad+2, AX
  154.  
  155.     mov SI, offset zones
  156.     call atp_&name&_real_define
  157.     or AX, AX
  158.     jnz fail
  159. endif
  160. ENDM
  161.  
  162. ATP_REAL_DEFINE_in_SI_out_AX MACRO name
  163.     local start, around, null_read, declare_failure, no_zone, arp_init
  164.     local r_init, stat_success, fail
  165.     .errb <zones>
  166.  
  167. ifdef atp_&name&_declared 
  168.     .DATA
  169.     atp_&name&_data     atp_data <>              ;; create storage needed
  170.     atp_&name&_read     DW ?
  171.     atp_&name&_wbuffer  DB  atp_&name&_wbuffsize dup (0)
  172.     atp_&name&_rqueue   atp_r_q_entry ATP_R_QUEUE_SIZE dup (<>)
  173.     dl_ip_&name&_ip     DD ?
  174.     dl_ip_&name&_mask   DD ?
  175.     dl_ip_&name&_net    DD ?
  176.     dl_ip_&name&_broad  DD ?
  177.     dl_ip_&name&_flags  DW ?
  178.     dl_ip_&name&_metric DW ?
  179.  
  180.     atp_&name&_arps     atp_arp_entry atp_&name&_nzones dup (<>)
  181.     DW 0                    ;; space for a final marker
  182.     DW 0                    ;; space for a final marker
  183.  
  184.     .CODE
  185.     jmp around
  186.         start:
  187.         ATP_TASK name
  188.             ;; this does NOT fall through
  189.  
  190.         null_read:
  191.             ATP_DL_IP_R_RETURN name
  192.                 ;; this does NOT fall through
  193.  
  194.     around:
  195.     atp_&name&_real_define:
  196.             ;; INITIALIZE THE APPLETALK STUFF
  197.     ATP_CHECK_DRIVER name, fail
  198.  
  199.     mov BX, offset atp_&name&_data.atp_Info_param
  200.     mov word ptr [BX+inf_command], ATGetNetInfo
  201.     CALL_ATP_in_BX_out_AX_const_BX_CX_DX_BP_SI_DI_ES name
  202.     cmp word ptr [BX+inf_status], 0
  203.     jz stat_success
  204.         mov AL, byte ptr dl_ip_&name&_ip+3
  205.         or AL, 80H
  206.         mov byte ptr [BX+inf_nodeid], AL
  207.         mov BX, offset atp_&name&_data.atp_Info_param
  208.         mov word ptr [BX+inf_command], ATInit
  209.         mov word ptr [BX+inf_status], -1
  210.         CALL_ATP_in_BX_out_AX_const_BX_CX_DX_BP_SI_DI_ES name
  211.         cmp word ptr [BX+inf_status], 0
  212.         jnz fail
  213.  
  214.         mov word ptr [BX+inf_command], ATGetNetInfo         ;; try again
  215.         CALL_ATP_in_BX_out_AX_const_BX_CX_DX_BP_SI_DI_ES name
  216.     stat_success:
  217.  
  218.     mov BX, offset atp_&name&_data.atp_DDP_param_in     ;; close in case it
  219.     mov word ptr [BX+ddp_command], DDPCloseSocket       ;; was open (that is
  220.     mov byte ptr [BX+ddp_socket], 72                    ;; we did not reboot)
  221.     mov byte ptr [BX+ddp_type], 22
  222.     CALL_ATP_in_BX_out_AX_const_BX_CX_DX_BP_SI_DI_ES name
  223.  
  224.     mov BX, offset atp_&name&_data.atp_DDP_param_in     ;; open read/write sock
  225.     mov word ptr [BX+ddp_command], DDPOpenSocket
  226.     mov byte ptr [BX+ddp_socket], 72
  227.     mov byte ptr [BX+ddp_type], 22
  228.     CALL_ATP_in_BX_out_AX_const_BX_CX_DX_BP_SI_DI_ES name
  229.     cmp word ptr [BX+ddp_status], 0
  230.     jnz fail
  231.  
  232.         ;; Set up stuff for resolving IP addreses (ARP)
  233.     mov DX, atp_&name&_nzones
  234.     mov BX, offset atp_&name&_arps
  235.     arp_init:
  236.         mov word ptr [BX+nbp_command], 0    ;; mark the end of the arp list
  237.         mov word ptr [BX+nbp_status], -205
  238.         and byte ptr [SI], 1FH              ;; cap length at 31
  239.         jz no_zone
  240.  
  241.             mov word ptr [BX+nbp_command], NBPLookup+AsyncMask
  242.             mov byte ptr [BX+nbp_toget], 1
  243.             mov byte ptr [BX+nbp_interval], 1
  244.             mov byte ptr [BX+nbp_retry], 1
  245.             mov AX, BX
  246.             add AX, atp_NBT_lookup
  247.             mov word ptr [BX+nbp_buffptr.buff_off], AX
  248.             mov AX, DS
  249.             mov word ptr [BX+nbp_buffptr.buff_seg], AX
  250.             mov word ptr [BX+nbp_buffsize], 64
  251.  
  252.             mov AX, DS
  253.             mov ES, AX
  254.             mov DI, BX
  255.             add DI, atp_buff_lookup+16
  256.             mov AX, 9 + ('I' * 256)
  257.             stosw
  258.             mov AX, 'P' + ('A' * 256)
  259.             stosw
  260.             mov AX, 'D' + ('D' * 256)
  261.             stosw
  262.             mov AX, 'R' + ('E' * 256)
  263.             stosw
  264.             mov AX, 'S' + ('S' * 256)
  265.             stosw
  266.             xor CX, CX
  267.             mov CL, [SI]
  268.             inc CX
  269.             rep
  270.             movsb
  271.  
  272.             mov AX, DS
  273.             mov word ptr [BX+nbp_entptr.buff_seg], AX
  274.             mov AX, word ptr dl_ip_&name&_ip
  275.             mov word ptr [BX+atp_ip_lookup], AX
  276.         no_zone:
  277.         add BX, size atp_arp_entry
  278.         dec DX
  279.     jnz arp_init
  280.     mov word ptr [BX+nbp_command], 0    ;; mark the end of the arp list
  281.  
  282.     ATP_DECLARE_IP_ADDRESS name, dl_ip_&name&_ip, fail
  283.  
  284.     mov BX, offset atp_&name&_rqueue
  285.     mov atp_&name&_data.atp_r_queue, BX
  286.     mov CX, ATP_R_QUEUE_SIZE 
  287.     r_init:
  288.         mov word ptr [BX+atp_q_rparam.ddp_command], DDPRead+AsyncMask
  289.         mov byte ptr [BX+atp_q_rparam.ddp_socket], 72
  290.         mov byte ptr [BX+atp_q_rparam.ddp_type], 22
  291.         mov word ptr [BX+atp_q_rparam.ddp_buffsize], 590
  292.         mov AX, BX
  293.         add AX, atp_q_rbuff
  294.         mov word ptr [BX+atp_q_rparam.ddp_buffptr+buff_off], AX
  295.         mov AX, DS
  296.         mov word ptr [BX+atp_q_rparam.ddp_buffptr+buff_seg], AX
  297.         mov word ptr [BX+atp_q_rparam.ddp_status], -1
  298.         CALL_ATP_in_BX_out_AX_const_BX_CX_DX_BP_SI_DI_ES name
  299.         add BX, size atp_r_q_entry
  300.         dec CX
  301.     jnz r_init
  302.  
  303.     TASK_DEFINE %atp_&name&_task, start          ;; start the task
  304.     mov word ptr atp_&name&_read, offset null_read
  305.  
  306.     BUFF_DEFINE %atp_&name&_wbuff
  307.     QUEUE_DEFINE %atp_&name&_wqueue
  308.     ARP_TAB_DEFINE %atp_&name&_arptab
  309.     xor AX, AX                                  ;; success return
  310.     RET
  311.  
  312.     fail:
  313.         xor AX, AX                              ;; fail return
  314.         dec AX
  315.         RET
  316. endif
  317. ENDM
  318.  
  319.  
  320. ;;****************************************************************************
  321. CALL_ATP_in_BX_out_AX_const_BX_CX_DX_BP_SI_DI_ES MACRO name
  322.     push    ds
  323.     push    es
  324.     int atp_&name&_interupt
  325.     pop es
  326.     pop ds
  327. ENDM
  328.  
  329.  
  330. ;;******************************************************************************
  331. ;;   DL_IP_R_READ name, code_label
  332. ;;       DL_IP_R_READ declares that the code starting at 'code_label'
  333. ;;       should be called whenever a IP packet is read.  BX:ES is initilized 
  334. ;;       to the begining of the IP packet before 'code_lable' is called
  335. ;;       The code at 'code_label' should call ARP_DL_IP_R_RETURN when it
  336. ;;       is done processing the packet.
  337. ;;       This procedure can only be called once per 'name'
  338. ;;
  339. ATP_DL_IP_R_READ MACRO name, code_label
  340.     .errb <code_label>
  341.  
  342.     mov word ptr atp_&name&_read, offset code_label
  343. ENDM
  344.  
  345. ;;******************************************************************************
  346. ;;   DL_IP_R_CONT_in_BX_CX_ES name, ok
  347. ;;       DL_IP_R_CONT determines if the packet returned by R_READ in BX:ES
  348. ;;       of length CX is continuous.  If it is it jumps to 'ok' otherwise
  349. ;;       it just returns
  350. ;;
  351. ATP_DL_IP_R_CONT_in_BX_CX_ES_const_BX_CX_DX_BP_SI_DI_ES MACRO name, ok
  352.     .errb <ok>
  353.     jmp ok                      ;; it is always continuous
  354. ENDM
  355.  
  356. ;;******************************************************************************
  357. ;;   DL_IP_R_RETURN name
  358. ;;       DL_IP_R_RETURN should be executed by the READ routine to signal
  359. ;;       that it is done processing the packet.
  360. ;;
  361. ATP_DL_IP_R_RETURN MACRO name
  362.     .errb <name>
  363.  
  364.     jmp atp_&name&_continue
  365. ENDM
  366.  
  367.  
  368. ;;******************************************************************************
  369. ;;   DL_IP_IS_BROADCAST_in_BX_ES name
  370. ;;      DL_IP_IS_BROADCAST_in_BX_ES determines if the packet pointed to
  371. ;;      by BX:ES is a broadcast and sets the zero flag if it is NOT a 
  372. ;;      broadcast
  373. ;;
  374. ATP_DL_IP_IS_BROADCAST_in_BX_ES_const_AX_BX_CX_DX_BP_DI_ES MACRO name
  375.     .errb <name>
  376.     cmp AX, AX                 ;; fake it and always say it NOT a broadcast
  377. ENDM
  378.  
  379.  
  380. ;;******************************************************************************
  381. ;;   DL_IP_W_ACCESS returns a pointer to an output buffer for a IP (network) 
  382. ;;   packet.  The buffer is at least min(CX, dl_ip_mtu) bytes long.  The 
  383. ;;   pointer is returned in DI.  If there is no buffer available
  384. ;;   this routine jumps to 'no_buffer'
  385. ;;
  386. ATP_DL_IP_W_ACCESS_in_CX_out_DI_ES_const_CX_BP MACRO name, no_buffer
  387.     local dequeued, dequeue_loop
  388.  
  389.         ;; release the entries of any packets that have been sent
  390.     dequeue_loop:
  391.         QUEUE_HEAD_out_SI_const_AX_BX_CX_DX_BP_DI_ES %atp_&name&_wqueue, dequeued
  392.         cmp [SI+atp_q_wparam+ddp_status], 0
  393.         jg dequeued
  394.         mov DI, [SI+atp_q_end]
  395.         BUFF_FREE_in_DI_const_AX_BX_CX_DX_BP_SI_DI_ES %atp_&name&_wbuff
  396.         QUEUE_DEQUEUE_in_SI_const_AX_BX_CX_DX_BP_DI_ES %atp_&name&_wqueue
  397.         jmp dequeue_loop
  398.     dequeued:
  399.  
  400.         ;; check if there is space for the next one to go out
  401.     BUFF_CHECK_in_CX_out_SI_DI_const_BX_CX_DX_BP_ES %atp_&name&_wbuff, no_buffer
  402.     mov DI, SI
  403.     mov SI, DS
  404.     mov ES, SI
  405. ENDM
  406.  
  407.  
  408. ;;******************************************************************************
  409. ;; DL_IP_W_WRITE_in_AX_CX name, broadcast
  410. ;;    DL_IP_W_WRITE actually signals the link layer to write a packet to the 
  411. ;;    network.  The packet is assumed to be in the buffer returned by 
  412. ;;    DL_IP_W_ACCESS.  CX is the length of the packet to send.   AX holds the 
  413. ;;    last two bytes of the IP address to send the packet to.  (notice we are 
  414. ;;    assuming a host portion of less than 16 bits).  if 'broadcast' is not 
  415. ;;    blank, then the packet is written to the broadcast address.  AX is 
  416. ;;    ignored in this case
  417. ;;
  418. ATP_DL_IP_W_WRITE_in_AX_CX_const_BP     MACRO name, broadcast
  419.     local done, got_haddr, wait_loop
  420.  
  421.     ATP_ARP_GET_in_AX_out_SI_const_CX_BP_DI_ES name, done
  422.     mov DX, SI                              ;; save hardware address
  423.  
  424.     BUFF_CHECK_in_CX_out_SI_DI_const_BX_CX_DX_BP_ES %atp_&name&_wbuff, done
  425.     mov BX, DI
  426.     QUEUE_ENQUEUE_out_DI_const_BX_CX_DX_BP_SI_ES %atp_&name&_wqueue, done
  427.     xchg BX, DI
  428.     BUFF_GET_in_DI_const_AX_BX_CX_DX_BP_SI_DI_ES %atp_&name&_wbuff
  429.     mov [BX+atp_q_end], DI
  430.     mov [BX+atp_q_wparam+ddp_buffptr+buff_off], SI
  431.     mov [BX+atp_q_wparam+ddp_buffsize], CX
  432.  
  433.     mov word ptr [BX+atp_q_wparam.ddp_command], DDPWrite+AsyncMask
  434.     mov AX, DS
  435.     mov word ptr [BX+atp_q_wparam.ddp_buffptr+buff_seg], AX
  436.     mov byte ptr [BX+atp_q_wparam.ddp_socket], 72
  437.     mov byte ptr [BX+atp_q_wparam.ddp_type], 22
  438.     mov word ptr [BX+atp_q_wparam.ddp_status], -1
  439.  
  440.     mov SI, DX
  441.     mov AX, [SI]                                ;; set hardware address
  442.     mov word ptr [BX+atp_q_wparam.ddp_addr.network], AX
  443.     mov AX, [SI+2]
  444.     mov word ptr [BX+atp_q_wparam.ddp_addr.nodeid], AX
  445.  
  446.     CALL_ATP_in_BX_out_AX_const_BX_CX_DX_BP_SI_DI_ES name
  447.     done:
  448. ENDM
  449.  
  450.  
  451. ;;******************************************************************************
  452. ;;   DL_IP_COPY_in_CX_SI_DI_ES_out_SI_DI interface
  453. ;;      DL_IP_COPY_in_CX_SI_DI_ES copys a packet from the input buffer (pointed 
  454. ;;      to by SI and the segement register given in IF_DECLARE) to an output 
  455. ;;      buffer (pointed to by DI and dest_reg) of length CX.   It assumes the
  456. ;;      output buffer is contiguous.  (and the caller shouldn't care if the 
  457. ;;      input buffer is contiguous)  COPY updates the pointers SI and DI
  458. ;;      to the end of the packet, and COPY could be called again if CX is not
  459. ;;      the total packet length (Note that CX MUST be even if you care about
  460. ;;      SI, and DI being updated properly)
  461. ;;
  462. ATP_DL_IP_COPY_in_CX_SI_DI_ES_out_SI_DI_const_BX_BP_ES MACRO name
  463.     .errb <name>
  464.  
  465.     inc CX
  466.     shr CX, 1
  467.     rep
  468.     movsw
  469. ENDM
  470.  
  471.  
  472. ;;******************************************************************************
  473. ;;   ATP_TASK is the read task that reads the next packet from the interface
  474. ;;   and dispatches it to the next higher protocol layer
  475. ;;
  476. ATP_TASK MACRO name
  477.     local done, inside
  478.     .errb <name>
  479.     .errb <task>
  480.  
  481.     mov BX, atp_&name&_data.atp_r_queue
  482.     add BX, size atp_r_q_entry
  483.     cmp BX, offset atp_&name&_rqueue + ((size atp_r_q_entry)*ATP_R_QUEUE_SIZE)
  484.     jb inside
  485.         mov BX, offset atp_&name&_rqueue
  486.     inside:
  487.     mov atp_&name&_data.atp_r_queue, BX
  488.  
  489.     cmp [BX+atp_q_rparam.ddp_status], 0
  490.     jg done                     ;; no packet yet
  491.     jl atp_&name&_continue          ;; error, resubmit the read 
  492.  
  493.         mov CX, [BX+atp_q_rparam.ddp_buffsize]
  494.         add BX, atp_q_rbuff
  495.         mov AX, DS
  496.         mov ES, AX
  497.         jmp word ptr atp_&name&_read
  498.  
  499.     atp_&name&_continue:
  500.         mov BX, atp_&name&_data.atp_r_queue
  501.         mov word ptr [BX+atp_q_wparam.ddp_buffsize], 590
  502.         mov word ptr [BX+atp_q_wparam.ddp_status], -1
  503.         CALL_ATP_in_BX_out_AX_const_BX_CX_DX_BP_SI_DI_ES name
  504.     done:
  505.     TASK_RETURN %atp_&name&_task
  506. ENDM
  507.  
  508.  
  509. ;;*****************************************************************************
  510. ;;  ATP_ARP_GET finds the hardware address for the IP address with the last
  511. ;;  two bytes in AX, and puts a pointer to the hardware address in SI.  
  512. ;;  This routine jumps to 'fail' if it cannot find the hardware address
  513. ;;  (for ATP a hardware address is a AddrBlk structure)
  514. ;;
  515. ATP_ARP_GET_in_AX_out_SI_const_CX_BP_DI_ES MACRO name, fail
  516.     local no_reply, chkstatus, arp_loop, done
  517.     .errb <fail>
  518.  
  519.     ARP_TAB_GET_in_AX_out_SI_const_AX_BX_CX_BP_DI_ES  %atp_&name&_arptab
  520.     jz done                                     ;; got the address
  521.  
  522.             ;; set up the arp calls
  523.     mov BX, offset atp_&name&_arps
  524.     chkstatus:
  525.         cmp [BX+nbp_status], 0
  526.         jg fail
  527.         jnz no_reply
  528.             dec word ptr [BX+nbp_status]
  529.             mov DX, AX                          ;; save AX
  530.             mov AX, DS
  531.             mov ES, AX
  532.  
  533.             mov SI, BX                          ;; save BX
  534.             mov BX, word ptr [BX+atp_ip_lookup+2]
  535.             mov AX, word ptr dl_ip_&name&_ip
  536.             LOG_PRINT_INET_in_AX_BX %mylog,L_ATALK,L_DEBUG,<Localtalk arp reply for IP address >
  537.             xchg BX, SI                         ;; restore BX, save AX
  538.             add BX, atp_NBT_lookup.ent_address
  539.  
  540.             mov AX, [BX]
  541.             xchg AH, AL
  542.             LOG_PRINT_REG_HEX %mylog,L_ATALK,L_DEBUG,<Locatalk address Net >, AX
  543.             mov AX, [BX+2]
  544.             LOG_PRINT_REG_HEX %mylog,L_ATALK,L_DEBUG,<Locatalk address socket:node >, AX
  545.             mov AX, SI                          ;; restore AX
  546.             ARP_TAB_ADD_in_AX_BX_ES_out_SI_const_BX_DX_BP_DI_ES %atp_&name&_arptab
  547.             sub BX, atp_NBT_lookup.ent_address
  548.             cmp DX, word ptr [BX+atp_ip_lookup+2]
  549.             jz done                             ;; a hit!!
  550.             mov AX, DX
  551.         no_reply:
  552.  
  553.         add BX, size atp_arp_entry
  554.         cmp [BX+nbp_command], 0
  555.     jnz chkstatus
  556.  
  557.     mov BX, word ptr dl_ip_&name&_ip
  558.     xchg AX, BX
  559.     LOG_PRINT_INET_in_AX_BX %mylog,L_ATALK,L_DEBUG,<Localtalk arp lookup >
  560.     mov AX, BX
  561.  
  562.     mov BX, offset atp_&name&_arps
  563.     arp_loop:
  564.         mov word ptr [BX+atp_ip_lookup+2], AX
  565.         push AX
  566.  
  567.         mov AX, DS
  568.         mov ES, AX
  569.         mov DI, BX
  570.         add DI, atp_buff_lookup+16
  571.         mov BP, DI
  572.         mov SI, BX
  573.         add SI, atp_ip_lookup
  574.         IP_ASCII_in_SI_DI_ES_out_DI_const_BX_BP_ES 
  575.         mov AX, BP
  576.         sub AX, DI
  577.         dec DI
  578.         mov [DI], AL
  579.         mov word ptr [BX+nbp_entptr.buff_off], DI
  580.  
  581.         CALL_ATP_in_BX_out_AX_const_BX_CX_DX_BP_SI_DI_ES  name
  582.         pop AX
  583.  
  584.         add BX, size atp_arp_entry
  585.         cmp [BX+nbp_command], 0
  586.     jnz arp_loop
  587.     jmp fail                        ;; we dont have the address
  588.     done:
  589. ENDM
  590.  
  591.  
  592. ;;*****************************************************************************
  593. ;; ATP_DECLARE_IP_ADDRESS registers the ip address at the address 'ip_address'
  594. ;; it jumps to 'fail' if it was not successful 
  595. ATP_DECLARE_IP_ADDRESS MACRO name, ip_address, fail
  596.     local success
  597.  
  598.         ;; declare my IP address to the world 
  599.     mov BX, offset atp_&name&_data.atp_NBTE_myip     ;; Set up NB Table entry
  600.     mov SI, offset atp_&name&_data.atp_Info_param
  601. xor AX, AX
  602.     mov AL, [SI+inf_nodeid]                         ;; node ID
  603.     mov [BX+tab_tuple.ent_address.nodeid], AL
  604.     mov AL, 72
  605.     mov [BX+tab_tuple.ent_address.socket], AL
  606.  
  607.     mov AX, DS
  608.     mov ES, AX
  609.     mov SI, offset ip_address
  610.     mov DI, offset atp_&name&_data.atp_NBTE_myip.tab_tuple.ent_name+16
  611.     mov BX, DI
  612.     IP_ASCII_in_SI_DI_ES_out_DI_const_BX_BP_ES 
  613.     mov SI, DI
  614.     sub BX, DI
  615.     mov CX, BX
  616.     mov DI, offset atp_&name&_data.atp_NBTE_myip.tab_tuple.ent_name
  617.     mov AL, CL
  618.     stosb
  619.     rep
  620.     movsb
  621.  
  622.     mov AX, 9 + ('I' * 256)
  623.     stosw
  624.     mov AX, 'P' + ('A' * 256)
  625.     stosw
  626.     mov AX, 'D' + ('D' * 256)
  627.     stosw
  628.     mov AX, 'R' + ('E' * 256)
  629.     stosw
  630.     mov AX, 'S' + ('S' * 256)
  631.     stosw
  632.     mov AX, 1 + ('*' * 256)
  633.     stosw
  634.  
  635.     mov BX, offset atp_&name&_data.atp_NBP_myip          ;; Set up NBP command
  636.     mov word ptr [BX+nbp_command], NBPRegister
  637.     mov SI, offset atp_&name&_data.atp_NBTE_myip     
  638.     mov word ptr [BX+nbp_buffptr.buff_off], SI
  639.     mov SI, DS
  640.     mov word ptr [BX+nbp_buffptr.buff_seg], SI
  641.     mov byte ptr [BX+nbp_interval], 1
  642.     mov byte ptr [BX+nbp_retry], 3
  643.     mov word ptr [BX+nbp_status], -205
  644.     CALL_ATP_in_BX_out_AX_const_BX_CX_DX_BP_SI_DI_ES name
  645.     cmp word ptr [BX+nbp_status], 0
  646.     jnz fail
  647. ENDM
  648.  
  649.  
  650. ;;***************************************************************************
  651. ;; ATP_CHECK_DRIVER does some (weak) checks to see of the appletalk driver
  652. ;; has been installed.  If not it jumps to 'fail'
  653. ;;
  654. ATP_CHECK_DRIVER MACRO name, fail
  655.  
  656.     xor AX, AX
  657.     mov ES, AX
  658.     mov DI, offset atp_&name&_interupt*4+2
  659.     mov AX, ES:[DI]
  660.     cmp AX, 100H            ;; Segment register must be above 4K
  661.     jb fail
  662.     cmp AX, 0C000H          ;; and less then C0000H
  663.     ja fail
  664. ENDM
  665.