home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / network / pcb121.zip / PACKET.INC < prev    next >
Text File  |  1992-01-23  |  12KB  |  373 lines

  1. ;;******************************************************************************
  2. ;;                         packet.inc      packet.inc
  3. ;;******************************************************************************
  4. ;;
  5. ;;  Copyright (C) 1989 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. ;; Vance Morrison 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. ;; packet.inc contains the interface driver for the the packet  driver 
  18. ;; (a la FTP software, drivers and info available from sun.soe.clarson.edu)
  19. ;;
  20. ;; Note that this interface driver is VERY inefficient.  basically packets
  21. ;; are copyied once on read and once again on write.   Thus this driver will
  22. ;; be at best 1/3 the speed of a native driver.  Nevertheless, this speed
  23. ;; may be acceptable, (and besides it gets all those people who want 3Com
  24. ;; support off my back).   There are other inefficiencies as well (saving
  25. ;; and restoring registers, waiting for packets to be sent etc), but even
  26. ;; so it will be usefull for low performance applications.
  27. ;;
  28. ;; Note that this these routines do not use any extended or high performance 
  29. ;; packet driver calls.  Only the basic calls are used
  30. ;;
  31. ;; The functions provided by this file are
  32. ;;
  33. ;;   PKT_DECLARE name, driver_int, driver_class, prom
  34. ;;   PKT_DEFINE name, fail
  35. ;;   PKT_IF_R_ACCESS_out_BX_CX_ES name, no_packet
  36. ;;   PKT_IF_R_CONT_in_BX_CX_ES_const_BX_CX_DX_BP_SI_DI_ES name, ok
  37. ;;   PKT_IF_R_FREE_const_BX_CX_BP_SI_DI_ES name
  38. ;;   PKT_IF_W_ACCESS_in_CX_out_DI_ES_const_BX_CX_BP name, no_buffer
  39. ;;   PKT_IF_W_WRITE_in_CX_const_BX_BP_ES name
  40. ;;   PKT_IF_SET_ADDRESS_in_SI_const_BX_CX_BP_DI_ES name
  41. ;;   PKT_IF_COPY_in_CX_SI_DI_ES_out_SI_DI_const_BX_BP_ES name
  42. ;;
  43. ;; Variables set by this module
  44. ;;
  45. ;;   pkt_&name&_declared                     ;; one if this interface exists
  46. ;;   if_&name&_address                       ;; the hardware address
  47. ;;   if_&name&_mtu                           ;; the maximum trans unit
  48. ;;
  49. ;;******************************************************************************
  50.  
  51. ;;******************************************************************************
  52. ;; data storage needed by this module
  53.  
  54. pkt_r_q_entry STRUC
  55.     pkt_q_rstart    DW ?
  56.     pkt_q_rend      DW ?
  57. pkt_r_q_entry ENDS
  58.  
  59. pkt_data  STRUC
  60.     pkt_handle      DW ?
  61.     pkt_bend        DW ?
  62.     pkt_bstart      DW ?
  63. pkt_data ENDS
  64.  
  65.  
  66. ;;******************************************************************************
  67. ;;   IF_DECLARE name, driver_int driver_class, promiscuous
  68. ;;       declares an interface object.  driver_int is the interupt number
  69. ;;   to use to access the packet driver (60H-80H).  driver_class is
  70. ;;   the packet driver class of the card (Ethernet = 1)
  71. ;;
  72. PKT_DECLARE MACRO name, driver_int, driver_class, promiscuous
  73.     .errb <name>
  74.     .errb <driver_int>
  75.  
  76.     .DATA
  77.     pkt_&name&_declared     = 1
  78.     pkt_&name&_drv_int   = driver_int
  79.     pkt_&name&_drv_class = driver_class
  80.  
  81.     pkt_&name&_rbuff   = name*100+1
  82.     pkt_&name&_rqueue  = name*100+2
  83.  
  84.     pkt_&name&_promiscuous = 0
  85.     ifnb <promiscuous>
  86.         pkt_&name&_promiscuous = 0&promiscuous
  87.     endif
  88.  
  89.     if_&name&_mtu = 1514
  90.     global pkt_&name&_wbuffer:byte
  91.     global pkt_&name&_rbuffer:byte
  92.     global pkt_&name&_data:pkt_data
  93.     global if_&name&_address:word 
  94.  
  95.     .CODE
  96.     global pkt_&name&_data_seg:word
  97.     global pkt_&name&_real_define:near
  98.     BUFF_DECLARE %pkt_&name&_rbuff, 10240, pkt_&name&_rbuffer
  99.     QUEUE_DECLARE %pkt_&name&_rqueue, 16, %(size pkt_r_q_entry)
  100. ENDM
  101.  
  102.  
  103. ;;******************************************************************************
  104. ;;   IF_DEFINE name, fail
  105. ;;      sets asside memory an name object and initializes it.  This
  106. ;;      routine is a no-op if 'name' was not declared.  It jumps to 'fail'
  107. ;;      if there was an error in  setup.
  108. ;;
  109. PKT_DEFINE MACRO name, fail
  110. ifdef pkt_&name&_declared
  111.     BUFF_DEFINE %pkt_&name&_rbuff 
  112.     QUEUE_DEFINE %pkt_&name&_rqueue
  113.     call pkt_&name&_real_define
  114.     or AX, AX
  115.     jnz fail
  116. endif
  117. ENDM
  118.  
  119.  
  120. PKT_REAL_DEFINE MACRO name
  121.     local pkt_read_task, got_driver, got_address, size_check, no_room, done
  122.     local set_prom
  123.     .errb <name>
  124.  
  125. ifdef pkt_&name&_declared
  126.     .DATA
  127.     if_&name&_address DW 3 DUP (0)
  128.     pkt_&name&_rbuffer DB 10240 dup (0)
  129.     pkt_&name&_wbuffer DB 1536 dup (0)
  130.     pkt_&name&_data    pkt_data      <>  ;; create storage needed
  131.  
  132.     .CODE
  133.     ;;*****************************************************************
  134.     pkt_&name&_real_define:
  135.     mov word ptr cs:pkt_&name&_data_seg, DS
  136.  
  137.     mov AH, 2           ;; access_type driver call
  138.     mov AL, pkt_&name&_drv_class    ;; driver class
  139.     mov DL, 0           ;; wildcard number
  140.     mov BX, 0FFFFH      ;; wildcard Type
  141.     xor CX, CX          ;; get any packet type 
  142.     mov DI, CS          ;; point to my packet reciever
  143.     mov ES, DI
  144.     mov DI, offset pkt_read_task
  145.     stc 
  146.     PKT_CALL_DRIVER name
  147.     jnc got_driver
  148.         mov DL, DH
  149.         xor DH, DH
  150.         mov AX, DX
  151.         ret
  152.     got_driver:
  153.     mov pkt_&name&_data.pkt_handle, AX
  154.  
  155.     mov BX, AX
  156.     mov AH, 6           ;; get ethernet address 
  157.     mov DX, DS
  158.     mov ES, DX
  159.     mov DI, offset if_&name&_address
  160.     mov CX, 6           ;; length of address buffer
  161.     stc
  162.     PKT_CALL_DRIVER name
  163.     jnc got_address
  164.         mov DL, DH
  165.         xor DH, DH
  166.         mov AX, DX
  167.         ret
  168.     got_address:
  169.  
  170.     if pkt_&name&_promiscuous eq 1
  171.         mov BX, pkt_&name&_data.pkt_handle
  172.         mov AH, 20      ;; set recieve mode
  173.         mov CX, 6       ;; to recieve all packets
  174.         stc
  175.         PKT_CALL_DRIVER name
  176.         jnc set_prom
  177.             mov DL, DH
  178.             xor DH, DH
  179.             mov AX, DX
  180.             ret
  181.         set_prom:
  182.     endif
  183.  
  184.     xor AX, AX
  185.     sti              ;; turn on interupts if they are not already on
  186.     ret
  187.  
  188.     ;;*********************************************************************
  189.     ;; 'interupt' routine
  190.     pkt_&name&_data_seg: DW 0
  191.  
  192.     pkt_read_task:
  193.     push DS
  194.     segcs
  195.     mov DS, word ptr pkt_&name&_data_seg
  196.     or AX, AX
  197.     jz size_check
  198.         QUEUE_ENQUEUE_out_DI_const_BX_CX_DX_BP_SI_ES %pkt_&name&_rqueue, done
  199.         mov AX, pkt_&name&_data.pkt_bstart
  200.         mov [DI+pkt_q_rstart], AX
  201.         mov AX, pkt_&name&_data.pkt_bend
  202.         mov [DI+pkt_q_rend], AX
  203.         done:
  204.         pop DS
  205.         retf
  206.     size_check:
  207.        BUFF_CHECK_in_CX_out_SI_DI_const_BX_CX_DX_BP_ES %pkt_&name&_rbuff,no_room
  208.            BUFF_GET_in_DI_const_AX_BX_CX_DX_BP_SI_DI_ES %pkt_&name&_rbuff
  209.            mov pkt_&name&_data.pkt_bstart, SI
  210.            mov pkt_&name&_data.pkt_bend, DI
  211.            mov DI, SI
  212.            mov AX, DS
  213.            mov ES, AX
  214.            pop DS
  215.            retf
  216.         no_room:
  217.            xor DI, DI
  218.            mov ES, DI
  219.            pop DS
  220.            retf
  221.  
  222. endif
  223. ENDM
  224.  
  225.  
  226. ;;******************************************************************************
  227. ;;   PKT_CLOSE
  228. ;;      closes the packet driver gracefully
  229. ;;
  230. PKT_CLOSE MACRO name
  231.     mov AH, 3               ;; CLOSE command
  232.     mov BX, pkt_&name&_data.pkt_handle
  233.     PKT_CALL_DRIVER name
  234. ENDM
  235.  
  236.  
  237. ;;******************************************************************************
  238. ;;   IF_R_ACCESS_out_BX_ES name, no_packet
  239. ;;       IF_R_ACCESS checks for the next packet to come from the the board
  240. ;;       associated with 'name' and returns a pointer to the begining of 
  241. ;;       an ethernet packet in BX:ES.  CX holds the length of the packet
  242. ;;       R_ACCESS jumps to 'no_packet' if there are no packets waiting to 
  243. ;;       be read in
  244. ;;       
  245. PKT_IF_R_ACCESS_out_BX_CX_ES MACRO name, no_packet
  246.     .errb <no_packet>
  247.  
  248.     QUEUE_HEAD_out_SI_const_AX_BX_CX_DX_BP_DI_ES %pkt_&name&_rqueue, no_packet
  249.     mov BX, [SI+pkt_q_rstart]
  250.     mov CX, [SI+pkt_q_rend]
  251.     sub CX, BX
  252.     mov AX, DS
  253.     mov ES, AX
  254. ENDM
  255.  
  256.  
  257. ;;******************************************************************************
  258. ;;   IF_R_FREE_const_BX_CX_BP_SI_DI_ES  name
  259. ;;       After the client is through processing the packet returned by 
  260. ;;       IF_R_ACCESS, IF_R_FREE must be called to inform 'name' that the 
  261. ;;       memory that the packet was in can be reused for future packets.
  262. ;;
  263. PKT_IF_R_FREE_const_BX_CX_BP_SI_DI_ES MACRO name
  264.     local done
  265.     .errb <name>
  266.  
  267.     cli
  268.     QUEUE_HEAD_out_SI_const_AX_BX_CX_DX_BP_DI_ES %pkt_&name&_rqueue, done
  269.     mov DI, [SI+pkt_q_rend]
  270.     BUFF_FREE_in_DI_const_AX_BX_CX_DX_BP_SI_DI_ES %pkt_&name&_rbuff
  271.     QUEUE_DEQUEUE_in_SI_const_AX_BX_CX_DX_BP_DI_ES %pkt_&name&_rqueue
  272.     done:
  273.     sti
  274. ENDM
  275.  
  276.  
  277. ;;******************************************************************************
  278. ;;   PKT_IF_R_CONT_in_BX_CX_ES name, ok
  279. ;;       IF_R_CONT determines if the packet returned by R_READ in BX:ES
  280. ;;       of length CX is continuous.  If it is it jumps to 'ok' otherwise
  281. ;;       it just returns
  282. ;;
  283. PKT_IF_R_CONT_in_BX_CX_ES_const_BX_CX_DX_BP_SI_DI_ES MACRO name, ok
  284.     .errb <ok>
  285.  
  286.     jmp ok      ;; is it always continuous
  287. ENDM
  288.  
  289.  
  290. ;;******************************************************************************
  291. ;;   IF_W_ACCESS_in_CX_out_DI_ES name, no_buffer
  292. ;;       IF_W_ACCESS returns a pointer to an output buffer for a packet.  The 
  293. ;;       pointer is returned in DI:ES.  If the ouptut buffer is busy, this 
  294. ;;       routine will jump to 'no_buffer'.  The output buffer  min(CX, 1536) 
  295. ;;       bytes long
  296. ;;
  297. PKT_IF_W_ACCESS_in_CX_out_DI_ES_const_BX_CX_BP MACRO name, no_buffer
  298.     .errb <no_buffer>
  299.  
  300.    mov DI, offset pkt_&name&_wbuffer
  301.    mov AX, DS
  302.    mov ES, AX
  303. ENDM
  304.  
  305.  
  306. ;;******************************************************************************
  307. ;;   IF_W_WRITE_in_CX name
  308. ;;       IF_W_WRITE actually signals the ethernet board to write a packet to 
  309. ;;       the ethernet.  The packet is assumed to be in the buffer returned by 
  310. ;;       IF_W_ACCESS. CX is the length of the packet to send.  
  311. ;;
  312. PKT_IF_W_WRITE_in_CX_const_BX_BP_ES MACRO name
  313.     .errb <name>
  314.  
  315.     push BX
  316.     push BP
  317.     push ES
  318.  
  319.     mov AH, 4               ;; set_pkt command
  320.     mov SI, offset pkt_&name&_wbuffer   ;; the packet to send
  321.                             ;; DS is OK as it stands
  322.                             ;; CX is also fine as is
  323.     PKT_CALL_DRIVER name
  324.     pop ES
  325.     pop BP
  326.     pop BX
  327. ENDM
  328.  
  329.  
  330. ;;******************************************************************************
  331. ;;   IF_SET_ADDRESS_in_SI name
  332. ;;       IF_SET_ADDRESS_in_SI sets the hardware address to be the value
  333. ;;       pointed to by SI.  Note this function may be a no-op if the
  334. ;;       hardware address cannot be set (ETHERNET for example)
  335. ;;
  336.  
  337. PKT_IF_SET_ADDRESS_in_SI_const_BX_CX_BP_DI_ES MACRO name
  338.     .err    ;; we don't support setting ethernet addresses (yet)
  339.     ENDM
  340.  
  341.  
  342. ;;******************************************************************************
  343. ;;   IF_COPY_in_CX_SI_DI_ES_out_SI_DI name
  344. ;;      IF_COPY_in_CX_SI_DI_ES copys a packet from the input buffer (pointed 
  345. ;;      to by SI and the segement register given in IF_DECLARE) to an output 
  346. ;;      buffer (pointed to by DI and ES) of length CX.   It assumes the
  347. ;;      output buffer is contiguous.  (and the caller shouln't care if the 
  348. ;;      input buffer is contiguous)
  349. ;;
  350. PKT_IF_COPY_in_CX_SI_DI_ES_out_SI_DI_const_BX_BP_ES MACRO name
  351.     .errb <name>
  352.  
  353.     ;; since DS points to the data segment, we are ready to go!!
  354.     inc CX
  355.     shr CX,1
  356.     rep movsw
  357. ENDM
  358.  
  359. ;;******************************************************************************
  360. ;; PKT_CALL_DRIVER calls the drivers, but it also makes sure that the
  361. ;; segment registers are preserved.
  362.  
  363. PKT_CALL_DRIVER MACRO name
  364.     .errb <name>
  365.  
  366.     push DS
  367.     push SS
  368.     int pkt_&name&_drv_int
  369.     pop SS
  370.     pop DS
  371. ENDM
  372.  
  373.