home *** CD-ROM | disk | FTP | other *** search
- ;;*****************************************************************************
- ;; atalk.inc atalk.inc
- ;;*****************************************************************************
- ;;
- ;; Copyright (C) 1989 Northwestern University, Vance Morrison
- ;;
- ;;
- ;; Permission to view, compile, and modify for LOCAL (intra-organization)
- ;; USE ONLY is hereby granted, provided that this copyright and permission
- ;; notice appear on all copies. Any other use by permission only.
- ;;
- ;; Northwestern University makes no representations about the suitability
- ;; of this software for any purpose. It is provided "as is" without expressed
- ;; or implied warranty. See the copywrite notice file for complete details.
- ;;
- ;;*****************************************************************************
- ;;
- ;; atalk.inc contains the DL_IP interface for the Appletalk protocols.
- ;; That is this module contains the code that wraps IP packets up into
- ;; appletalk packets before sending them out, and unencapsulates incomming
- ;; IP packets. As far has IP is concerned this is just a DL_IP interface
- ;;
- ;; This module assumes that there is a Apple localtalk card (or Flashcard)
- ;; installed in the computer and the Appletalk drivers have been loaded
- ;; (atalk.sys or atalk.exe). This module does not implement appletalk,
- ;; it just calls the driver with wrapped up IP packets.
- ;;
- ;; ATP_DECLARE name, interupt, task
- ;; ATP_DEFINE name, ip_address, ip_mask
- ;; ATP_DL_IP_R_READ name, code_label
- ;; ATP_DL_IP_R_CONT_in_BX_CX_ES_const_BX_CX_DX_BP_SI_DI_ES name, ok
- ;; ATP_DL_IP_RETURN name
- ;; ATP_DL_IP_W_ACCESS_in_CX_out_DI_ES_const_CX_BP name, fail
- ;; ATP_DL_IP_W_WRITE_in_AX_CX_const_BP name, broadcast
- ;; ATP_DL_IP_IS_BROADCAST_in_BX_ES_const_AX_BX_CX_DX_BP_DI_ES name
- ;; ATP_DL_IP_COPY_in_CX_SI_DI_ES_out_SI_DI_const_BX_BP_ES name
- ;;
- ;; Variables Provided by this module (READ ONLY!!!!)
- ;;
- ;; atp_&name&_declared 1 if this object has been declared
- ;; dl_ip_&name&_ip the IP address
- ;; dl_ip_&name&_mask the network mask
- ;; dl_ip_&name&_net the network (IP addr bitwize AND ip_mask)
- ;; dl_ip_&name&_broad the network broadcast address
- ;; dl_ip_&name&_flags A word exclusively for IP use
- ;; dl_ip_&name&_metric The interface metric (for routing use)
- ;; dl_ip_&name&_mtu the Maximum transmission unit (packet size)
- ;;
- ;;*****************************************************************************
-
-
- ;;*****************************************************************************
- ;; data storage needed by this module
-
- include at.inc ;; FLASHCARD interface defs
-
- atp_w_q_entry STRUC
- atp_q_wparam DDPParams <> ;; this MUST be first
- atp_q_end DW ?
- atp_w_q_entry ENDS
-
- atp_arp_entry STRUC
- atp_NBP_lookup NBPparams <> ;; THIS MUST BE FIRST
- atp_NBT_lookup NBPTuple <>
- atp_ip_lookup db 4 DUP (0) ;; IP address to look up
- atp_buff_lookup db 64 DUP (0) ;; buffer to hold NBP name to look up
- atp_arp_entry ENDS
-
- ATP_R_QUEUE_SIZE = 3 ;; size of the read queue
-
- atp_r_q_entry STRUC
- atp_q_rparam DDPParams <> ;; this must be first
- atp_q_rbuff DB 590 DUP (0) ;; stuff needed for read
- atp_r_q_entry ENDS
-
- atp_data STRUC
- atp_DDP_param_in DDPParams <>
- atp_Info_param InfoParams <> ;; stuff needed for initilization
- atp_NBP_myip NBPparams <>
- atp_NBTE_myip NBPTabEntry <>
- atp_r_queue DW ?
- atp_data ENDS
-
-
- ;;*****************************************************************************
- ;; ATP_DECLARE name, interupt, task
- ;; ATP_DECLARE declares all the external defintions for the ATP object
- ;;
- ATP_DECLARE MACRO name, interupt, task, wqueuesize, wbuffsize, num_zones
- .errb <wbuffsize>
-
- atp_&name&_declared = 1
- atp_&name&_interupt = interupt
- atp_&name&_task = task
- atp_&name&_wqueuesize = wqueuesize
- atp_&name&_wbuffsize = wbuffsize
- atp_&name&_wbuff = name*100+1
- atp_&name&_wqueue = name*100+2
- atp_&name&_arptab = name*100+3
- ifb <num_zones>
- atp_&name&_nzones = 3
- else
- atp_&name&_nzones = num_zones
- endif
- atp_&name&_zbuff_len = atp_&name&_nzones*16+5
- dl_ip_&name&_mtu = 578
-
- .DATA
- global dl_ip_&name&_ip:dword
- global dl_ip_&name&_mask:dword
- global dl_ip_&name&_net:dword
- global dl_ip_&name&_broad:dword
- global dl_ip_&name&_flags:word
- global dl_ip_&name&_metric:word
- global atp_&name&_data:atp_data
- global atp_&name&_read:word
- global atp_&name&_arps:atp_arp_entry
- global atp_&name&_wbuffer:byte
- global atp_&name&_rqueue:atp_r_q_entry
- dl_ip_&name&_haddr = (atp_&name&_data.atp_Info_param.inf_network)
- .CODE
- global atp_&name&_continue:near
- global atp_&name&_real_define:near
-
- BUFF_DECLARE %atp_&name&_wbuff, wbuffsize, atp_&name&_wbuffer
- QUEUE_DECLARE %atp_&name&_wqueue, wqueuesize, %(size atp_w_q_entry)
- ARP_TAB_DECLARE %atp_&name&_arptab
- ENDM
-
-
- ;;*****************************************************************************
- ;; ATP_DEFINE name, ip_address, ip_mask, fail
- ;;
- ATP_DEFINE MACRO name, ip_address, ip_mask, zones, fail
-
- ifdef atp_&name&_declared
-
- mov AX, word ptr ip_address ;; copy over params
- mov BX, 0FFFFH ;; Force our assumtion
- mov word ptr dl_ip_&name&_ip, AX
- mov word ptr dl_ip_&name&_net, AX
- mov word ptr dl_ip_&name&_broad, AX
- mov word ptr dl_ip_&name&_mask, BX
-
- mov AX, word ptr ip_address+2
- mov BX, word ptr ip_mask+2
- mov word ptr dl_ip_&name&_ip+2, AX
- mov word ptr dl_ip_&name&_mask+2, BX
- and AX, BX
- mov word ptr dl_ip_&name&_net+2, AX
- not BX
- or AX, BX
- mov word ptr dl_ip_&name&_broad+2, AX
-
- mov SI, offset zones
- call atp_&name&_real_define
- or AX, AX
- jnz fail
- endif
- ENDM
-
- ATP_REAL_DEFINE_in_SI_out_AX MACRO name
- local start, around, null_read, declare_failure, no_zone, arp_init
- local r_init, stat_success, fail
- .errb <zones>
-
- ifdef atp_&name&_declared
- .DATA
- atp_&name&_data atp_data <> ;; create storage needed
- atp_&name&_read DW ?
- atp_&name&_wbuffer DB atp_&name&_wbuffsize dup (0)
- atp_&name&_rqueue atp_r_q_entry ATP_R_QUEUE_SIZE dup (<>)
- dl_ip_&name&_ip DD ?
- dl_ip_&name&_mask DD ?
- dl_ip_&name&_net DD ?
- dl_ip_&name&_broad DD ?
- dl_ip_&name&_flags DW ?
- dl_ip_&name&_metric DW ?
-
- atp_&name&_arps atp_arp_entry atp_&name&_nzones dup (<>)
- DW 0 ;; space for a final marker
- DW 0 ;; space for a final marker
-
- .CODE
- jmp around
- start:
- ATP_TASK name
- ;; this does NOT fall through
-
- null_read:
- ATP_DL_IP_R_RETURN name
- ;; this does NOT fall through
-
- around:
- atp_&name&_real_define:
- ;; INITIALIZE THE APPLETALK STUFF
- ATP_CHECK_DRIVER name, fail
-
- mov BX, offset atp_&name&_data.atp_Info_param
- mov word ptr [BX+inf_command], ATGetNetInfo
- CALL_ATP_in_BX_out_AX_const_BX_CX_DX_BP_SI_DI_ES name
- cmp word ptr [BX+inf_status], 0
- jz stat_success
- mov AL, byte ptr dl_ip_&name&_ip+3
- or AL, 80H
- mov byte ptr [BX+inf_nodeid], AL
- mov BX, offset atp_&name&_data.atp_Info_param
- mov word ptr [BX+inf_command], ATInit
- mov word ptr [BX+inf_status], -1
- CALL_ATP_in_BX_out_AX_const_BX_CX_DX_BP_SI_DI_ES name
- cmp word ptr [BX+inf_status], 0
- jnz fail
-
- mov word ptr [BX+inf_command], ATGetNetInfo ;; try again
- CALL_ATP_in_BX_out_AX_const_BX_CX_DX_BP_SI_DI_ES name
- stat_success:
-
- mov BX, offset atp_&name&_data.atp_DDP_param_in ;; close in case it
- mov word ptr [BX+ddp_command], DDPCloseSocket ;; was open (that is
- mov byte ptr [BX+ddp_socket], 72 ;; we did not reboot)
- mov byte ptr [BX+ddp_type], 22
- CALL_ATP_in_BX_out_AX_const_BX_CX_DX_BP_SI_DI_ES name
-
- mov BX, offset atp_&name&_data.atp_DDP_param_in ;; open read/write sock
- mov word ptr [BX+ddp_command], DDPOpenSocket
- mov byte ptr [BX+ddp_socket], 72
- mov byte ptr [BX+ddp_type], 22
- CALL_ATP_in_BX_out_AX_const_BX_CX_DX_BP_SI_DI_ES name
- cmp word ptr [BX+ddp_status], 0
- jnz fail
-
- ;; Set up stuff for resolving IP addreses (ARP)
- mov DX, atp_&name&_nzones
- mov BX, offset atp_&name&_arps
- arp_init:
- mov word ptr [BX+nbp_command], 0 ;; mark the end of the arp list
- mov word ptr [BX+nbp_status], -205
- and byte ptr [SI], 1FH ;; cap length at 31
- jz no_zone
-
- mov word ptr [BX+nbp_command], NBPLookup+AsyncMask
- mov byte ptr [BX+nbp_toget], 1
- mov byte ptr [BX+nbp_interval], 1
- mov byte ptr [BX+nbp_retry], 1
- mov AX, BX
- add AX, atp_NBT_lookup
- mov word ptr [BX+nbp_buffptr.buff_off], AX
- mov AX, DS
- mov word ptr [BX+nbp_buffptr.buff_seg], AX
- mov word ptr [BX+nbp_buffsize], 64
-
- mov AX, DS
- mov ES, AX
- mov DI, BX
- add DI, atp_buff_lookup+16
- mov AX, 9 + ('I' * 256)
- stosw
- mov AX, 'P' + ('A' * 256)
- stosw
- mov AX, 'D' + ('D' * 256)
- stosw
- mov AX, 'R' + ('E' * 256)
- stosw
- mov AX, 'S' + ('S' * 256)
- stosw
- xor CX, CX
- mov CL, [SI]
- inc CX
- rep
- movsb
-
- mov AX, DS
- mov word ptr [BX+nbp_entptr.buff_seg], AX
- mov AX, word ptr dl_ip_&name&_ip
- mov word ptr [BX+atp_ip_lookup], AX
- no_zone:
- add BX, size atp_arp_entry
- dec DX
- jnz arp_init
- mov word ptr [BX+nbp_command], 0 ;; mark the end of the arp list
-
- ATP_DECLARE_IP_ADDRESS name, dl_ip_&name&_ip, fail
-
- mov BX, offset atp_&name&_rqueue
- mov atp_&name&_data.atp_r_queue, BX
- mov CX, ATP_R_QUEUE_SIZE
- r_init:
- mov word ptr [BX+atp_q_rparam.ddp_command], DDPRead+AsyncMask
- mov byte ptr [BX+atp_q_rparam.ddp_socket], 72
- mov byte ptr [BX+atp_q_rparam.ddp_type], 22
- mov word ptr [BX+atp_q_rparam.ddp_buffsize], 590
- mov AX, BX
- add AX, atp_q_rbuff
- mov word ptr [BX+atp_q_rparam.ddp_buffptr+buff_off], AX
- mov AX, DS
- mov word ptr [BX+atp_q_rparam.ddp_buffptr+buff_seg], AX
- mov word ptr [BX+atp_q_rparam.ddp_status], -1
- CALL_ATP_in_BX_out_AX_const_BX_CX_DX_BP_SI_DI_ES name
- add BX, size atp_r_q_entry
- dec CX
- jnz r_init
-
- TASK_DEFINE %atp_&name&_task, start ;; start the task
- mov word ptr atp_&name&_read, offset null_read
-
- BUFF_DEFINE %atp_&name&_wbuff
- QUEUE_DEFINE %atp_&name&_wqueue
- ARP_TAB_DEFINE %atp_&name&_arptab
- xor AX, AX ;; success return
- RET
-
- fail:
- xor AX, AX ;; fail return
- dec AX
- RET
- endif
- ENDM
-
-
- ;;****************************************************************************
- CALL_ATP_in_BX_out_AX_const_BX_CX_DX_BP_SI_DI_ES MACRO name
- push ds
- push es
- int atp_&name&_interupt
- pop es
- pop ds
- ENDM
-
-
- ;;******************************************************************************
- ;; DL_IP_R_READ name, code_label
- ;; DL_IP_R_READ declares that the code starting at 'code_label'
- ;; should be called whenever a IP packet is read. BX:ES is initilized
- ;; to the begining of the IP packet before 'code_lable' is called
- ;; The code at 'code_label' should call ARP_DL_IP_R_RETURN when it
- ;; is done processing the packet.
- ;; This procedure can only be called once per 'name'
- ;;
- ATP_DL_IP_R_READ MACRO name, code_label
- .errb <code_label>
-
- mov word ptr atp_&name&_read, offset code_label
- ENDM
-
- ;;******************************************************************************
- ;; DL_IP_R_CONT_in_BX_CX_ES name, ok
- ;; DL_IP_R_CONT determines if the packet returned by R_READ in BX:ES
- ;; of length CX is continuous. If it is it jumps to 'ok' otherwise
- ;; it just returns
- ;;
- ATP_DL_IP_R_CONT_in_BX_CX_ES_const_BX_CX_DX_BP_SI_DI_ES MACRO name, ok
- .errb <ok>
- jmp ok ;; it is always continuous
- ENDM
-
- ;;******************************************************************************
- ;; DL_IP_R_RETURN name
- ;; DL_IP_R_RETURN should be executed by the READ routine to signal
- ;; that it is done processing the packet.
- ;;
- ATP_DL_IP_R_RETURN MACRO name
- .errb <name>
-
- jmp atp_&name&_continue
- ENDM
-
-
- ;;******************************************************************************
- ;; DL_IP_IS_BROADCAST_in_BX_ES name
- ;; DL_IP_IS_BROADCAST_in_BX_ES determines if the packet pointed to
- ;; by BX:ES is a broadcast and sets the zero flag if it is NOT a
- ;; broadcast
- ;;
- ATP_DL_IP_IS_BROADCAST_in_BX_ES_const_AX_BX_CX_DX_BP_DI_ES MACRO name
- .errb <name>
- cmp AX, AX ;; fake it and always say it NOT a broadcast
- ENDM
-
-
- ;;******************************************************************************
- ;; DL_IP_W_ACCESS returns a pointer to an output buffer for a IP (network)
- ;; packet. The buffer is at least min(CX, dl_ip_mtu) bytes long. The
- ;; pointer is returned in DI. If there is no buffer available
- ;; this routine jumps to 'no_buffer'
- ;;
- ATP_DL_IP_W_ACCESS_in_CX_out_DI_ES_const_CX_BP MACRO name, no_buffer
- local dequeued, dequeue_loop
-
- ;; release the entries of any packets that have been sent
- dequeue_loop:
- QUEUE_HEAD_out_SI_const_AX_BX_CX_DX_BP_DI_ES %atp_&name&_wqueue, dequeued
- cmp [SI+atp_q_wparam+ddp_status], 0
- jg dequeued
- mov DI, [SI+atp_q_end]
- BUFF_FREE_in_DI_const_AX_BX_CX_DX_BP_SI_DI_ES %atp_&name&_wbuff
- QUEUE_DEQUEUE_in_SI_const_AX_BX_CX_DX_BP_DI_ES %atp_&name&_wqueue
- jmp dequeue_loop
- dequeued:
-
- ;; check if there is space for the next one to go out
- BUFF_CHECK_in_CX_out_SI_DI_const_BX_CX_DX_BP_ES %atp_&name&_wbuff, no_buffer
- mov DI, SI
- mov SI, DS
- mov ES, SI
- ENDM
-
-
- ;;******************************************************************************
- ;; DL_IP_W_WRITE_in_AX_CX name, broadcast
- ;; DL_IP_W_WRITE actually signals the link layer to write a packet to the
- ;; network. The packet is assumed to be in the buffer returned by
- ;; DL_IP_W_ACCESS. CX is the length of the packet to send. AX holds the
- ;; last two bytes of the IP address to send the packet to. (notice we are
- ;; assuming a host portion of less than 16 bits). if 'broadcast' is not
- ;; blank, then the packet is written to the broadcast address. AX is
- ;; ignored in this case
- ;;
- ATP_DL_IP_W_WRITE_in_AX_CX_const_BP MACRO name, broadcast
- local done, got_haddr, wait_loop
-
- ATP_ARP_GET_in_AX_out_SI_const_CX_BP_DI_ES name, done
- mov DX, SI ;; save hardware address
-
- BUFF_CHECK_in_CX_out_SI_DI_const_BX_CX_DX_BP_ES %atp_&name&_wbuff, done
- mov BX, DI
- QUEUE_ENQUEUE_out_DI_const_BX_CX_DX_BP_SI_ES %atp_&name&_wqueue, done
- xchg BX, DI
- BUFF_GET_in_DI_const_AX_BX_CX_DX_BP_SI_DI_ES %atp_&name&_wbuff
- mov [BX+atp_q_end], DI
- mov [BX+atp_q_wparam+ddp_buffptr+buff_off], SI
- mov [BX+atp_q_wparam+ddp_buffsize], CX
-
- mov word ptr [BX+atp_q_wparam.ddp_command], DDPWrite+AsyncMask
- mov AX, DS
- mov word ptr [BX+atp_q_wparam.ddp_buffptr+buff_seg], AX
- mov byte ptr [BX+atp_q_wparam.ddp_socket], 72
- mov byte ptr [BX+atp_q_wparam.ddp_type], 22
- mov word ptr [BX+atp_q_wparam.ddp_status], -1
-
- mov SI, DX
- mov AX, [SI] ;; set hardware address
- mov word ptr [BX+atp_q_wparam.ddp_addr.network], AX
- mov AX, [SI+2]
- mov word ptr [BX+atp_q_wparam.ddp_addr.nodeid], AX
-
- CALL_ATP_in_BX_out_AX_const_BX_CX_DX_BP_SI_DI_ES name
- done:
- ENDM
-
-
- ;;******************************************************************************
- ;; DL_IP_COPY_in_CX_SI_DI_ES_out_SI_DI interface
- ;; DL_IP_COPY_in_CX_SI_DI_ES copys a packet from the input buffer (pointed
- ;; to by SI and the segement register given in IF_DECLARE) to an output
- ;; buffer (pointed to by DI and dest_reg) of length CX. It assumes the
- ;; output buffer is contiguous. (and the caller shouldn't care if the
- ;; input buffer is contiguous) COPY updates the pointers SI and DI
- ;; to the end of the packet, and COPY could be called again if CX is not
- ;; the total packet length (Note that CX MUST be even if you care about
- ;; SI, and DI being updated properly)
- ;;
- ATP_DL_IP_COPY_in_CX_SI_DI_ES_out_SI_DI_const_BX_BP_ES MACRO name
- .errb <name>
-
- inc CX
- shr CX, 1
- rep
- movsw
- ENDM
-
-
- ;;******************************************************************************
- ;; ATP_TASK is the read task that reads the next packet from the interface
- ;; and dispatches it to the next higher protocol layer
- ;;
- ATP_TASK MACRO name
- local done, inside
- .errb <name>
- .errb <task>
-
- mov BX, atp_&name&_data.atp_r_queue
- add BX, size atp_r_q_entry
- cmp BX, offset atp_&name&_rqueue + ((size atp_r_q_entry)*ATP_R_QUEUE_SIZE)
- jb inside
- mov BX, offset atp_&name&_rqueue
- inside:
- mov atp_&name&_data.atp_r_queue, BX
-
- cmp [BX+atp_q_rparam.ddp_status], 0
- jg done ;; no packet yet
- jl atp_&name&_continue ;; error, resubmit the read
-
- mov CX, [BX+atp_q_rparam.ddp_buffsize]
- add BX, atp_q_rbuff
- mov AX, DS
- mov ES, AX
- jmp word ptr atp_&name&_read
-
- atp_&name&_continue:
- mov BX, atp_&name&_data.atp_r_queue
- mov word ptr [BX+atp_q_wparam.ddp_buffsize], 590
- mov word ptr [BX+atp_q_wparam.ddp_status], -1
- CALL_ATP_in_BX_out_AX_const_BX_CX_DX_BP_SI_DI_ES name
- done:
- TASK_RETURN %atp_&name&_task
- ENDM
-
-
- ;;*****************************************************************************
- ;; ATP_ARP_GET finds the hardware address for the IP address with the last
- ;; two bytes in AX, and puts a pointer to the hardware address in SI.
- ;; This routine jumps to 'fail' if it cannot find the hardware address
- ;; (for ATP a hardware address is a AddrBlk structure)
- ;;
- ATP_ARP_GET_in_AX_out_SI_const_CX_BP_DI_ES MACRO name, fail
- local no_reply, chkstatus, arp_loop, done
- .errb <fail>
-
- ARP_TAB_GET_in_AX_out_SI_const_AX_BX_CX_BP_DI_ES %atp_&name&_arptab
- jz done ;; got the address
-
- ;; set up the arp calls
- mov BX, offset atp_&name&_arps
- chkstatus:
- cmp [BX+nbp_status], 0
- jg fail
- jnz no_reply
- dec word ptr [BX+nbp_status]
- mov DX, AX ;; save AX
- mov AX, DS
- mov ES, AX
-
- mov SI, BX ;; save BX
- mov BX, word ptr [BX+atp_ip_lookup+2]
- mov AX, word ptr dl_ip_&name&_ip
- LOG_PRINT_INET_in_AX_BX %mylog,L_ATALK,L_DEBUG,<Localtalk arp reply for IP address >
- xchg BX, SI ;; restore BX, save AX
- add BX, atp_NBT_lookup.ent_address
-
- mov AX, [BX]
- xchg AH, AL
- LOG_PRINT_REG_HEX %mylog,L_ATALK,L_DEBUG,<Locatalk address Net >, AX
- mov AX, [BX+2]
- LOG_PRINT_REG_HEX %mylog,L_ATALK,L_DEBUG,<Locatalk address socket:node >, AX
- mov AX, SI ;; restore AX
- ARP_TAB_ADD_in_AX_BX_ES_out_SI_const_BX_DX_BP_DI_ES %atp_&name&_arptab
- sub BX, atp_NBT_lookup.ent_address
- cmp DX, word ptr [BX+atp_ip_lookup+2]
- jz done ;; a hit!!
- mov AX, DX
- no_reply:
-
- add BX, size atp_arp_entry
- cmp [BX+nbp_command], 0
- jnz chkstatus
-
- mov BX, word ptr dl_ip_&name&_ip
- xchg AX, BX
- LOG_PRINT_INET_in_AX_BX %mylog,L_ATALK,L_DEBUG,<Localtalk arp lookup >
- mov AX, BX
-
- mov BX, offset atp_&name&_arps
- arp_loop:
- mov word ptr [BX+atp_ip_lookup+2], AX
- push AX
-
- mov AX, DS
- mov ES, AX
- mov DI, BX
- add DI, atp_buff_lookup+16
- mov BP, DI
- mov SI, BX
- add SI, atp_ip_lookup
- IP_ASCII_in_SI_DI_ES_out_DI_const_BX_BP_ES
- mov AX, BP
- sub AX, DI
- dec DI
- mov [DI], AL
- mov word ptr [BX+nbp_entptr.buff_off], DI
-
- CALL_ATP_in_BX_out_AX_const_BX_CX_DX_BP_SI_DI_ES name
- pop AX
-
- add BX, size atp_arp_entry
- cmp [BX+nbp_command], 0
- jnz arp_loop
- jmp fail ;; we dont have the address
- done:
- ENDM
-
-
- ;;*****************************************************************************
- ;; ATP_DECLARE_IP_ADDRESS registers the ip address at the address 'ip_address'
- ;; it jumps to 'fail' if it was not successful
- ATP_DECLARE_IP_ADDRESS MACRO name, ip_address, fail
- local success
-
- ;; declare my IP address to the world
- mov BX, offset atp_&name&_data.atp_NBTE_myip ;; Set up NB Table entry
- mov SI, offset atp_&name&_data.atp_Info_param
- xor AX, AX
- mov AL, [SI+inf_nodeid] ;; node ID
- mov [BX+tab_tuple.ent_address.nodeid], AL
- mov AL, 72
- mov [BX+tab_tuple.ent_address.socket], AL
-
- mov AX, DS
- mov ES, AX
- mov SI, offset ip_address
- mov DI, offset atp_&name&_data.atp_NBTE_myip.tab_tuple.ent_name+16
- mov BX, DI
- IP_ASCII_in_SI_DI_ES_out_DI_const_BX_BP_ES
- mov SI, DI
- sub BX, DI
- mov CX, BX
- mov DI, offset atp_&name&_data.atp_NBTE_myip.tab_tuple.ent_name
- mov AL, CL
- stosb
- rep
- movsb
-
- mov AX, 9 + ('I' * 256)
- stosw
- mov AX, 'P' + ('A' * 256)
- stosw
- mov AX, 'D' + ('D' * 256)
- stosw
- mov AX, 'R' + ('E' * 256)
- stosw
- mov AX, 'S' + ('S' * 256)
- stosw
- mov AX, 1 + ('*' * 256)
- stosw
-
- mov BX, offset atp_&name&_data.atp_NBP_myip ;; Set up NBP command
- mov word ptr [BX+nbp_command], NBPRegister
- mov SI, offset atp_&name&_data.atp_NBTE_myip
- mov word ptr [BX+nbp_buffptr.buff_off], SI
- mov SI, DS
- mov word ptr [BX+nbp_buffptr.buff_seg], SI
- mov byte ptr [BX+nbp_interval], 1
- mov byte ptr [BX+nbp_retry], 3
- mov word ptr [BX+nbp_status], -205
- CALL_ATP_in_BX_out_AX_const_BX_CX_DX_BP_SI_DI_ES name
- cmp word ptr [BX+nbp_status], 0
- jnz fail
- ENDM
-
-
- ;;***************************************************************************
- ;; ATP_CHECK_DRIVER does some (weak) checks to see of the appletalk driver
- ;; has been installed. If not it jumps to 'fail'
- ;;
- ATP_CHECK_DRIVER MACRO name, fail
-
- xor AX, AX
- mov ES, AX
- mov DI, offset atp_&name&_interupt*4+2
- mov AX, ES:[DI]
- cmp AX, 100H ;; Segment register must be above 4K
- jb fail
- cmp AX, 0C000H ;; and less then C0000H
- ja fail
- ENDM
-