home *** CD-ROM | disk | FTP | other *** search
- ;;*****************************************************************************
- ;; ether.inc ether.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.
- ;;
- ;;*****************************************************************************
- ;;
- ;; ether.inc constains the board independant, ethernet processing that needs
- ;; to be done. I rely only on the IF interface defined in if.inc.
- ;;
- ;; The functions provided by this file are
- ;;
- ;; ETH_DECLARE name, interface, task
- ;; ETH_DEFINE name
- ;; ETH_R_READ name, type, code_label
- ;; ETH_R_RETURN name
- ;; ETH_R_CONT_in_BX_CX_ES_const_BX_CX_DX_BP_SI_DI_ES name, ok
- ;; ETH_W_ACCESS_in_CX_out_DI_ES_const_BX_CX_BP name, no_buffer
- ;; ETH_W_WRITE_in_AX_CX_SI_DI_ES_const_BX_BP_ES name
- ;; ETH_IS_BROADCAST_in_BX_ES_const_AX_BX_CX_DX_BP_DI_ES name
- ;; ETH_COPY_in_CX_SI_DI_ES_out_SI_DI_const_BX_BP_ES name
- ;;
- ;; Variables Provided by this module (READ ONLY!!!!)
- ;;
- ;; eth_&name&_declared 1 if this module is declared
- ;; eth_&name&_address The hardware address
- ;; eth_&name&_mtu The maximum transmission unit
- ;;
- ;;*****************************************************************************
-
-
- ;;*****************************************************************************
- ;; defs for ethernet structures
-
- IP_TYPE = 0800h
- SWAPPED_IP_TYPE = 0008h
- ARP_TYPE = 0806h
- SWAPPED_ARP_TYPE = 0608h
-
- ether STRUC
- ether_dst DB 6 DUP (0)
- ether_src DB 6 DUP (0)
- ether_type DW 0
- ether ENDS
-
- ;;*****************************************************************************
- ;; data storage needed by this module
-
- eth_data STRUC
- eth_type_tab dw 256 dup (0)
- eth_w_try db ?
- eth_data ENDS
-
-
- ;;*****************************************************************************
- ;; ETH_DECLARE name, interface, task
- ;; creates a new data link object. 'name' is the name of this new
- ;; object. 'interface' is the name of the interface to that will provide
- ;; the low level services this module will need. 'task' is the name
- ;; of a task that we need
- ;;
- ETH_DECLARE MACRO name, interface, task
- .errb <task>
-
- .DATA
- eth_&name&_declared = 1
- eth_&name&_interface = interface
- eth_&name&_task = task
- eth_&name&_address = if_&interface&_address
- eth_&name&_mtu = 1500 ;; maximum transmission unit
-
- global eth_&name&_data:eth_data
- .CODE
- global eth_&name&_continue:near
- global eth_&name&_real_define:near
- ENDM
-
-
- ;;*****************************************************************************
- ;; ETH_DEFINE name
- ;; ETH_DEFINE declare all the things that have to be defined in
- ;; every independantly assembled module. ETH declares those
- ;; things that need be be done only once (in particular memory allocation
- ;; and initialzation code). Every module including the one ETH_DEFINE
- ;; is in) must have a ETH_DELCARE.
- ;;
- ETH_DEFINE MACRO name
-
- call eth_&name&_real_define
- ENDM
-
- ETH_REAL_DEFINE MACRO name
- local start, around
- .errb <name>
-
- ifdef eth_&name&_declared
- .DATA
- eth_&name&_data eth_data <> ;; create storage needed
-
- .CODE
- jmp around
- start:
- ETH_TASK name
- ;; this does NOT fall through
- around:
- eth_&name&_real_define:
- mov AX, DS ;; initilize table
- mov ES, AX
- mov AX, offset eth_&name&_continue
- mov DI, offset eth_&name&_data.eth_type_tab
- mov CX, 256
- rep
- stosw
-
- TASK_DEFINE %eth_&name&_task, start ;; start the task
- RET
- endif
- ENDM
-
-
- ;;******************************************************************************
- ;; ETH_R_READ name, type, code_label
- ;; ETH_R_READ declares that code starting at 'code_label' should be
- ;; called whenever a packet with type 'type' is read from the IF.
- ;; The code is called with BX:ES pointing to the start of the packet
- ;; CX loaded with the length of the packet and AX loaded with the
- ;; type of the packet. The code should
- ;; execute ETH_R_RETURN when it is through.
- ;;
- ETH_R_READ MACRO name, type, code_label
- local jmp_entry
- .errb <code_label>
-
- jmp_entry = eth_&name&_data.eth_type_tab+2*((type / 256) xor (type mod 256))
-
- mov word ptr jmp_entry, offset code_label
- ENDM
-
- ;;******************************************************************************
- ;; ETH_R_CONT_in_BX_CX_ES name, ok
- ;; ETH_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
- ;;
- ETH_R_CONT_in_BX_CX_ES_const_BX_CX_DX_BP_SI_DI_ES MACRO name, ok
- .errb <ok>
-
- IF_R_CONT_in_BX_CX_ES_const_BX_CX_DX_BP_SI_DI_ES %eth_&name&_interface, ok
- ENDM
-
- ;;******************************************************************************
- ;; ETH_R_RETURN
- ;; ETH_R_RETURN should be called at the end of the read code to signal
- ;; that the read code is finished with the packet read in
- ;;
- ETH_R_RETURN MACRO name
- .errb <name>
-
- jmp eth_&name&_continue
- ENDM
-
-
- ;;******************************************************************************
- ;; ETH_W_ACCESS_in_CX_out_DI_ES name, no_buffer
- ;; ETH_W_ACCESS returns a pointer to an output buffer for a (network)
- ;; packet. The pointer is returned in DI:ES. If the output buffer is
- ;; busy, this routine jump to 'no_buffer'. The buffer return will
- ;; be at least min(CX, 1500) bytes long
- ;;
- ETH_W_ACCESS_in_CX_out_DI_ES_const_BX_CX_BP MACRO name, no_buffer
- .errb <no_buffer>
-
- add CX, size ether
- IF_W_ACCESS_in_CX_out_DI_ES_const_BX_CX_BP %eth_&name&_interface, no_buffer
- sub CX, size ether
- add DI, size ether ;; make it point to the Data part
- ENDM
-
-
- ;;******************************************************************************
- ;; ETH_W_WRITE_in_AX_CX_SI_DI_ES name, type
- ;; ETH_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
- ;; ETH_W_ACCESS. CX is the length of the packet to send. SI:DS holds
- ;; is a pointer to the hardware destination address. AX is the
- ;; type code of the ethernet packet to send.
- ;; DI:ES MUST point be the pointer returned by W_ACCESS_out_DI_ES
- ;;
- ETH_W_WRITE_in_AX_CX_SI_DI_ES_const_BX_BP_ES MACRO name
- local size_ok
- .errb <name>
-
- add CX, size ether
- cmp CX, 64
- jae size_ok
- mov CX, 64
- size_ok:
- sub DI, size ether
- movsw
- movsw
- movsw
-
- mov SI, offset eth_&name&_address
- movsw
- movsw
- movsw
-
- stosw
- IF_W_WRITE_in_CX_const_BX_BP_ES %eth_&name&_interface
- ENDM
-
-
-
- ;;******************************************************************************
- ;; ETH_IS_BROADCAST_in_BX_ES name
- ;; ETH_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
- ;;
- ETH_IS_BROADCAST_in_BX_ES_const_AX_BX_CX_DX_BP_DI_ES MACRO name
- .errb <name>
-
- mov SI, BX
- sub SI, size ether
- test byte ptr ES:[SI], 80H
- ENDM
-
-
- ;;******************************************************************************
- ;; ETH_COPY_in_CX_SI_DI_ES_out_SI_DI interface
- ;; ETH_COPY_in_CX_SI_DI_ES copies 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)
- ;;
- ETH_COPY_in_CX_SI_DI_ES_out_SI_DI_const_BX_BP_ES MACRO name
- .errb <name>
- IF_COPY_in_CX_SI_DI_ES_out_SI_DI_const_BX_BP_ES %eth_&name&_interface
- ENDM
-
-
- ;;******************************************************************************
- ;; ETH_TASK is the read task that reads the next packet from the interface
- ;; and dispatches it to the next higher protocol layer
- ;;
- ETH_TASK MACRO name
- local done
- .errb <name>
-
- IF_R_ACCESS_out_BX_CX_ES %eth_&name&_interface, done
- mov AX, word ptr ES:[BX+ether_type]
- add BX, size ether
- sub CX, size ether
-
- xor DX, DX ;; compute hash function
- mov DL, AH
- xor DL, AL
- shl DX, 1
- mov SI, DX ;;assume perfect hash function
- jmp [SI+eth_&name&_data.eth_type_tab]
-
- eth_&name&_continue:
- IF_R_FREE_const_BX_CX_BP_SI_DI_ES %eth_&name&_interface
-
- done:
- TASK_RETURN %eth_&name&_task
- ENDM
-
-