home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / packetdrivers.tar.gz / pd.tar / new / pktdll.asm < prev    next >
Assembly Source File  |  1993-09-11  |  34KB  |  1,358 lines

  1.     page 66, 132
  2. ; PKTDLL.ASM Version 1.2 - provides Packet Driver interface over Digital's DLL.
  3. ;
  4. ; (c) Copyright Brian F. Angus 1993.  All rights reserved.
  5. ;
  6. ; PKTDLL was renamed from DLLPKT to fit with Digital Equipment Corporation's
  7. ; naming conventions and the left to right reading habits of the western
  8. ; world
  9. ;
  10. ; Big credits to: Harry P.E. Stox for the "c" version of DLLPKT (v0.1)
  11. ;          Daniel D. Lanciani for code chunks from ODIPKT and DIS_PKT
  12. ;          Joe R. Doupnik for code chunks from DIS_PKT
  13. ;          Chris Lord and Mitch Lichtenberg - they know who they are
  14. ;
  15. ; This unmodified source file and its executable form may be used and
  16. ; redistributed freely.  The source may be modified, and the source or
  17. ; executable versions built from the modified source may be used and
  18. ; redistributed, provided that this notice and the copyright displayed by
  19. ; the exectuable remain intact, and provided that the executable displays
  20. ; an additional message indicating that it has been modified, and by whom.
  21. ;
  22. ; Brian F. Angus releases this software "as is", with no express or
  23. ; implied warranty, including, but not limited to, the implied warranties
  24. ; of merchantability and fitness for a particular purpose.
  25. ;
  26. ; Please send bug reports to angus@trcoa.enet.dec.com or
  27. ;
  28. ; Brian Angus
  29. ; Digital Equipment of Canada
  30. ; 505 University Avenue
  31. ; Toronto, Ontario M5G 2H2
  32. ; CANADA
  33.  
  34. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  35. ;; Equates                  ;;
  36. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  37.  
  38. ; Miscellaneous Stuff
  39. carry            equ 0001h    ; carry bit in flag register
  40. cr            equ 13        ; carriage return
  41. tab            equ 9        ; tab
  42. eol            equ <13,10>    ; end of line
  43. eos            equ <13,10,'$'>    ; end of string
  44. hd1Int            equ 08h        ; 1st bank of IRQ vectors
  45. hd2Int            equ 70h        ; 2nd bank of IRQ vectors
  46.  
  47. ; DIX Ethernet Specific
  48. ethMaxFrame        equ 1514    ; maximum frame size
  49. ethMinFrame        equ 60        ; minimum frame size
  50. ethAddrLen        equ 6        ; length of ethernet address
  51. ethTypeLen        equ 2        ; length of ethernet type field
  52. ethHeadLen        equ 14        ; lenfth of ethernet header
  53. ethDataLen        equ 1500    ; length of ethernet data field
  54.  
  55. ; Packet Driver Specific
  56. pktFunction        equ 5        ; basic and high performance functions
  57. pktClass        equ 1        ; driver class (DIX ethernet)
  58. pktType            equ -1        ; driver type (match any)
  59. pktNumber        equ 0        ; driver number
  60. pktVersion        equ 10        ; driver version number
  61. pktInt            equ 61h        ; driver interrupt (default)
  62. maxHandles        equ 8        ; max active handles
  63. txBufCount        equ 8        ; back to back transmits
  64. rxBufCount        equ 8        ; back to back receives
  65.  
  66. ; Packet Driver Function Calls
  67. pktNotImplemented    equ 0        ; function not implemented
  68. pktDriverInfo        equ 1        ; get driver information
  69. pktAccessType        equ 2        ; open handle for protocol
  70. pktReleaseType        equ 3        ; close handle for protocol
  71. pktSendPkt        equ 4        ; transmit a packet
  72. pktTerminate        equ 5        ; unload driver if possible
  73. pktGetAddress        equ 6        ; get ethernet address
  74. pktResetInterface    equ 7        ; reset ethernet card and driver
  75. pktStopUpcalls        equ 8        ; stop upcalls to applications
  76. pktGetParameters    equ 10        ; get extended driver information
  77. pktAsSendPkt        equ 11        ; high performance transmit
  78. pktSetRcvMode        equ 20        ; set receive mode
  79. pktGetRcvMode        equ 21        ; get receive mode
  80. pktSetMulticastList    equ 22        ; set multicast list
  81. pktGetMulticastList    equ 23        ; get multicast list
  82. pktGetStatistics    equ 24        ; get statistics
  83. pktSetAddress        equ 25        ; set ethernet address
  84.  
  85. ; Packet Driver Return Codes
  86. pkterrBadHandle        equ 1        ; invalid handle number
  87. pkterrNoClass        equ 2        ; no interfaces of this class found
  88. pkterrNoType        equ 3        ; no interfaces of this type found
  89. pkterrNoNumber        equ 4        ; no interfaces of this number found
  90. pkterrBadType        equ 5        ; bad packet type specified
  91. pkterrNoMulticast    equ 6        ; multicasts not supported
  92. pkterrCantTerminate    equ 7        ; packet driver cannot terminate
  93. pkterrBadMode        equ 8        ; invalid receiver mode specified
  94. pkterrNoSpace        equ 9        ; insufficient space for operation
  95. pkterrTypeInuse        equ 10        ; type is currently in use
  96. pkterrBadCommand    equ 11        ; command is not implemented
  97. pkterrCantSend        equ 12        ; packet couldn't be sent
  98. pkterrCantSet        equ 13        ; hardware address couldn't be changed
  99. pkterrBadAddress    equ 14        ; invalid hardware address
  100. pkterrCantReset        equ 15        ; couldn't reset interface
  101.  
  102. ; DLL Specific
  103. schInt            equ 6ch        ; interrupt for scheduler
  104. dllInt            equ 69h        ; interrupt for datalink
  105. dllNoPad        equ 0        ; don't pad ethernet message
  106. dllPadMessage        equ 1        ; pad message to minimum size
  107. dllMode802        equ 0        ; 802.3 compatibility mode for Novell
  108. dllModeDIX        equ 1        ; DIX frame formats
  109. dllModePromis        equ 2        ; promiscuous mode (all frames)
  110.  
  111. ; DLL Function Calls - (the 0a00h is the DLL module id for the AH register)
  112. dllInit            equ 0a00h+0    ; initialize datalink functions
  113. dllOpen            equ 0a00h+1    ; open a portal
  114. dllClose        equ 0a00h+2    ; close a portal
  115. dllEnbMulti        equ 0a00h+3    ; enable a multicast address
  116. dllDisMulti        equ 0a00h+4    ; disable a multicast address
  117. dllTransmit        equ 0a00h+5    ; transmit a message
  118. dllRequestXmit        equ 0a00h+6    ; request a transmit buffer
  119. dllDeallocate        equ 0a00h+7    ; free a buffer
  120. dllReadChan        equ 0a00h+8    ; read channel status
  121. dllReadPlist        equ 0a00h+9    ; read portal list
  122. dllReadPortal        equ 0a00h+10    ; read portal status
  123. dllReadCount        equ 0a00h+11    ; read/zero counters
  124. dllNetworkBoot        equ 0a00h+12    ; remote boot (not implemented)
  125. dllEnableChan        equ 0a00h+13    ; emable channel
  126. dllDisabChan        equ 0a00h+14    ; disable channel
  127. dllStartMOP        equ 0a00h+15    ; enable MOP portals
  128. dllStopMOP        equ 0a00h+16    ; disable MOP portals
  129. dllReaDecparm        equ 0a00h+17    ; read DECPARM.DAT address
  130. dllSetDecparm        equ 0a00h+18    ; set DECPARM.DAT address
  131. dllExtLoopback        equ 0a00h+19    ; do external loopback
  132. dllGetPDB        equ 0a00h+20    ; get portal database pointer
  133. dllGetPrivInfo        equ 0a00h+25    ; get private information
  134. dllGetRemBoot        equ 0a00h+26    ; get remote boot information
  135. dllDisMOPmulti        equ 0a00h+29    ; disable MOP multicast
  136. dllEnaMOPmulti        equ 0a00h+30    ; enable MOP multicast
  137. dllInsCheck        equ 0a00h+31    ; installation check
  138. dllReqSized        equ 0a00h+33    ; request sized transmit buffer
  139. dllExtCount        equ 0a00h+40    ; extended counters
  140. dllReadChar        equ 0a00h+41    ; read characteristics
  141.  
  142. ; DLL Return Codes
  143. dllerrNotImpl        equ -1        ; not implemented
  144. dllerrSuccess        equ 0        ; function call succeeded
  145. dllerrInitFail        equ 1        ; initialization failed
  146. dllerrChNotOff        equ 2        ; channel not off
  147. dllerrStateOff        equ 3        ; channel is off
  148. dllerrNoAddr        equ 4        ; address has not been set
  149. dllerrNoHW        equ 5        ; hardware is broken
  150. dllerrBuf2Smal        equ 6        ; buffer is too small
  151. dllerrNoneAvl        equ 7        ; no more buffers available
  152. dllerrNoResrc        equ 8        ; no resources available
  153. dllerrPromAct        equ 9        ; promiscuous receiver is active
  154. dllerrNonExcl        equ 10        ; promiscuous receiver already active
  155. dllerrUnRec        equ 11        ; unrecognised portal
  156. dllerrPTinuse        equ 12        ; protocol type in use
  157. dllerrNotMulti        equ 13        ; address is not a multicast address
  158. dllerrOutStand        equ 14        ; portal has outstanding calls active
  159. dllerrNoRXbad        equ 15        ; hardware does not support bad frames
  160. dllerrNoneOut        equ 16        ; no receive buffers to be cancelled
  161. dllerrNoEvents        equ 17        ; no events in queue
  162. dllerrBroken        equ 18        ; port driver is broken
  163. dllerrExQuota        equ 19        ; exceeded quota
  164. dllerrAlInit        equ 20        ; already initialized
  165. dllerrLBfail        equ 21        ; loopback failure
  166. dllerrIllBuf        equ 22        ; illegal buffer freed
  167. dllerrInvCmd        equ 23        ; invalid command
  168.  
  169. ; DOS Errorlevel Codes
  170. doserrSuccess        equ 0        ; normal completion
  171. doserrFixMEM        equ 1        ; wrong memory address    - fixed
  172. doserrFixIRQ        equ 2        ; wrong IRQ level    - fixed
  173. doserrFixDMA        equ 3        ; wrong DMA channel    - fixed
  174. doserrFixIO        equ 4        ; wrong IO address    - fixed
  175. doserrExists        equ 5        ; packet driver already loaded
  176. doserrCableFail        equ 20        ; general cable failure
  177. doserrCableOpen        equ 21        ; network cable is open
  178. doserrCableShort    equ 22        ; network cable is shorted
  179. doserrUsage        equ 30        ; usage message
  180. doserrRange        equ 31        ; arguments out of range
  181. doserrError        equ 32        ; unspecified initialization error
  182. doserrBadMEM        equ 34        ; wrong memory address
  183. doserrBadIRQ        equ 35        ; wrong IRQ level
  184. doserrBadDMA        equ 36        ; wrong DMA channel
  185. doserrNoCard        equ 37        ; wrong IO address or no network card
  186.  
  187. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  188. ;; Structures Definitions          ;;
  189. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  190.  
  191. ETH    struc                ; structure of DIX ethernet packet
  192.     ethDestAddr    db ethAddrLen dup(?) ; destination address
  193.     ethSourceAddr    db ethAddrLen dup(?) ; source address
  194.     ethType        db ethTypeLen dup(?) ; protocol type
  195.     ethData        db ethDataLen dup(?) ; data
  196. ETH    ends
  197.  
  198. HND    struc                ; structure of handle block
  199.     hndInUse    db ?        ; handle in use flag
  200.     hndPerm        db ?        ; permanent handle for Windows
  201.     hndPortalID    dw ?        ; portal id
  202.     hndType        db ethTypeLen dup(?) ; protocol type
  203.     hndReceive    dd ?        ; receive packet routine
  204. HND    ends
  205.  
  206. PRM    struc                ; structure of parameter block
  207.     prmMajorRev    db 1        ; major revision = 1
  208.     prmMinorRev    db 9        ; minor revision = 9
  209.     prmParamLen    db 14        ; length of this structure = 14
  210.     prmAddrLen    db ethAddrLen    ; MAC addr length
  211.     prmMTU        dw ethMaxFrame    ; MAC packet length
  212.     prmMulticastAval dw 0        ; no multicast support
  213.     prmRcvBuffs    dw rxBufCount - 1 ; back-to-back RX -1
  214.     prmXmtBufs    dw txBufCount - 1 ; back-to-back TX -1
  215.     prmIntNum    dw 0        ; EOI interrupt
  216. PRM    ends
  217.  
  218. DCB    struc                ; structure of DLL control block
  219.     dcbPortalID    dw ?        ; portal ID
  220.     dcbSaddr    db ethAddrLen dup(?) ; ethernet source address
  221.     dcbDaddr    db ethAddrLen dup(?) ; ethernet destination address
  222.     dcbBufferPtr    dd ?        ; buffer address
  223.     dcbBufferLen    dw ?        ; buffer length
  224.     dcbOperation    dw ?        ; DCB operation
  225.     dcbPad        db ?        ; pad mode (open)
  226.     dcbMode        db ?        ; mode (open)
  227.     dcbLScallback    dd ?        ; line state callback
  228.     dcbRXcallback    dd ?        ; receive callback
  229.     dcbTXcallback    dd ?        ; transmit callback
  230.     dcbMaxOut    db ?        ; maximum outstanding
  231.     dcbPtype    db ethTypeLen dup(?) ; protocol type
  232.     dcbTXhandle    dw ?        ; transmit handle
  233. DCB    ends
  234.  
  235. UCB    struc                ; structure of user callback block
  236.     ucbPortalID    dw ?        ; portal ID
  237.     ucbDaddr    db ethAddrLen dup(?) ; destination address
  238.     ucbSaddr    db ethAddrLen dup(?) ; source address
  239.     ucbBufferPtr    dd ?        ; buffer address
  240.     ucbBufferLen    dw ?        ; buffer length
  241.     ucbBufStatus    db ?        ; buffer status
  242.     ucbBufReason    db ?        ; buffer reason
  243.     ucbTXhandle    dw ?        ; transmit handle
  244. UCB    ends
  245.  
  246. PSB    struc                ; structure of portal status block
  247.     psbBufLost    dw ?        ; number of lost buffers
  248.     psbPtype    db ethTypeLen dup(?) ; protocol type
  249. PSB    ends
  250.  
  251. DWP    struc                ; structure of double word pointer
  252.     offs        dw ?        ; define as 0
  253.     segm        dw ?        ; define as 2
  254. DWP    ends
  255.  
  256. R16    struc                ; stack offsets of 16 bit registers
  257.     _es        dw ?        ; es register
  258.     _ds        dw ?        ; ds register
  259.     _bp        dw ?        ; bp register
  260.     _di        dw ?        ; di register
  261.     _si        dw ?        ; si register
  262.     _dx        dw ?        ; dx register
  263.     _cx        dw ?        ; cx register
  264.     _bx        dw ?        ; bx register
  265.     _ax        dw ?        ; ax register
  266.     _ip        dw ?        ; ip register
  267.     _cs        dw ?        ; cs register
  268.     _flags        dw ?        ; flag register
  269. R16    ends
  270.  
  271. R08    struc                ; stack offsets of 8 bit registers
  272.             dw 5 dup(?)    ; es, ds, bp, di, si registers
  273.     _dl        db ?        ; dl register
  274.     _dh        db ?        ; dh register
  275.     _cl        db ?        ; cl register
  276.     _ch        db ?        ; ch register
  277.     _bl        db ?        ; bl register
  278.     _bh        db ?        ; bh register
  279.     _al        db ?        ; al register
  280.     _ah        db ?        ; ah register
  281. R08    ends
  282.  
  283. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  284. ;; Main Code Segment              ;;
  285. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  286.  
  287. CODE    segment word public 'CODE'
  288.     assume cs:CODE, ds:CODE, es:nothing, ss:CODE
  289.  
  290.     org    2ch
  291. envSeg    label    word
  292.     org    80h
  293. cmdBuf    label    byte
  294.     org    100h
  295. at100h:    jmp    start
  296.  
  297. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  298. ;; Driver Data                  ;;
  299. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  300.  
  301. pktName    db    'PKTDLL', 0        ; driver name used by driver_info
  302. ether    db    ethAddrLen dup(?)    ; ethernet address
  303. pktVec    dw    pktInt * 4        ; default driver vector address
  304.  
  305. param    PRM    <>            ; parameter block
  306.  
  307. hndTab    HND    maxHandles dup(<>)    ; the handle table
  308. hndEnd    label    byte
  309.  
  310. pList    dw    maxHandles dup(?)    ; active portal list
  311. pStat    PSB    <>            ; portal status block (partial)
  312.  
  313. flag802    db    0            ; novell 802.3 flag
  314.  
  315. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  316. ;; Check for Windows or Task Switcher ;;
  317. ;;  regs inp: none              ;;
  318. ;;  regs out: flags              ;;
  319. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  320.  
  321. safe:    mov    cx, 'DE'        ; check for DESQview
  322.     mov    dx, 'SQ'
  323.     mov    ax, 2b01h
  324.     int    21h
  325.     cmp    al, -1
  326.     mov    ax, 1
  327.     jne    safe1
  328.  
  329.     mov    ax, 4680h        ; check for DOS 5.0 shell
  330.     int    2fh
  331.     cmp    ax, 0
  332.     mov    ax, 2
  333.     jz    safe1
  334.  
  335.     mov    ax, 1600h        ; check for MS-Windows
  336.     int    2fh
  337.     mov    ah, 0
  338.     cmp    al, 0
  339.     jz    safe1
  340.     cmp    al, 80h
  341.     mov    al, 0
  342.     jz    safe1
  343.     mov    ax, 3
  344. safe1:    cmp    ax, 0
  345.     ret                ; "z" bit is clear if ok
  346.  
  347. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  348. ;; Send Packet Common Subroutine      ;;
  349. ;;  regs inp: ds,si,cx              ;;
  350. ;;  regs out: none              ;;
  351. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  352.  
  353. send:    cmp    cx, ethMaxFrame        ; check packet size
  354.     ja    send4
  355.     cmp    cx, ethMinFrame
  356.     jnb    send1
  357.     mov    cx, ethMinFrame
  358. send1:    sub    cx, ethHeadLen        ; adjust packet size
  359.  
  360.     mov    ax, word ptr [si].ethType ; get protocol type
  361.  
  362.     mov    di, offset hndTab    ; address handle table
  363. send2:    cmp    cs:[di].hndInUse, 1    ; find matching handle
  364.     jne    send3
  365.     cmp    word ptr cs:[di].hndType, ax
  366.     je    send5
  367. send3:    add    di, size HND
  368.     cmp    di, offset hndEnd
  369.     jb    send2
  370.  
  371. send4:    add    sp, 2            ; pop off our return address
  372.     mov    dh, pkterrCantSend    ; return can't send error
  373.     jmp    bad
  374.  
  375. send5:    push    bp            ; save register pointer
  376.     sub    sp, size DCB        ; allocate DCB on stack
  377.     mov    ax, ss
  378.     mov    es, ax
  379.     mov    bx, sp
  380.     mov    bp, sp
  381.  
  382.     mov    ax, cs:[di].hndPortalID ; store portal ID
  383.     mov    [bp].dcbPortalID, ax
  384.  
  385.     mov    ax, dllRequestXmit    ; allocate buffer
  386.     int    dllInt
  387.     cmp    ax, dllerrSuccess
  388.     jne    send6
  389.  
  390.     mov    [bp].dcbBufferLen, cx    ; store more DCB info
  391.     mov    ax, word ptr cs:[di].hndType
  392.     mov    word ptr [bp].dcbPType, ax
  393.  
  394.     push    si            ; store destination address
  395.     push    cx
  396.     lea    di, [bp].dcbDaddr
  397.     lea    si, [si].ethDestAddr
  398.     mov    cx, ethAddrLen / 2
  399.     rep    movsw
  400.     pop    cx
  401.     pop    si
  402.  
  403.     push    es            ; store packet buffer
  404.     les    di, [bp].dcbBufferPtr
  405.     lea    si, [si].ethData
  406.     clc
  407.     rcr    cx, 1
  408.     rep    movsw
  409.     rcl    cx, 1
  410.     rep    movsb
  411.     pop    es
  412.  
  413.     mov    ax, dllTransmit        ; transmit buffer
  414.     int    dllInt
  415.  
  416. send6:    add    sp, size DCB        ; deallocate DCB
  417.     pop    bp            ; restore register pointer
  418.  
  419.     cmp    ax, dllerrSuccess
  420.     jne    send4
  421.     ret
  422.  
  423. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  424. ;; DLL RX and TX Upcalls          ;;
  425. ;;  regs inp: es,bx              ;;
  426. ;;  regs out: none              ;;
  427. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  428.  
  429. rx_upc:    push    es            ; save UCB pointer
  430.     push    bx
  431.  
  432.     mov    dx, es:[bx].ucbPortalID    ; get portal ID
  433.     mov    cx, es:[bx].ucbBufferLen; get buffer length
  434.     add    cx, ethHeadLen
  435.  
  436.     mov    ax, cs            ; address data segment
  437.     mov    ds, ax
  438.  
  439.     mov    bx, offset hndTab    ; address handle table
  440. rx1:    cmp    [bx].hndInUse, 1    ; find matching handle
  441.     jne    rx2
  442.     cmp    [bx].hndPortalID, dx
  443.     je    rx3
  444. rx2:    add    bx, size HND
  445.     cmp    bx, offset hndEnd
  446.     jb    rx1
  447.     jmp    short rx5
  448.  
  449. rx3:    push    bx            ; request application buffer
  450.     push    cx
  451.     push    word ptr [bx].hndType
  452.     xor    ax, ax
  453.     call    [bx].hndReceive
  454.     pop    ax
  455.     pop    cx
  456.     pop    dx
  457.  
  458.     mov    bx, es            ; check for null pointer
  459.     cmp    bx, 0
  460.     jne    rx4
  461.     cmp    di, 0
  462.     je    rx5
  463.  
  464. rx4:    mov    bp, sp            ; address UCB
  465.     lds    bx, [bp]
  466.  
  467.     push    cx            ; save buffer length
  468.     push    es            ; save buffer pointer
  469.     push    di
  470.  
  471.     cld                ; copy buffer to application
  472.     lea    si, [bx].ucbDaddr    ;  destination
  473.     mov    cx, ethAddrLen / 2
  474.     rep    movsw
  475.     lea    si, [bx].ucbSaddr    ;  source
  476.     mov    cx, ethAddrLen / 2
  477.     rep    movsw
  478.     stosw                ;  protocol type
  479.     mov    cx, [bx].ucbBufferLen    ;  ethernet data
  480.     lds    si, [bx].ucbBufferPtr
  481.     clc
  482.     rcr    cx, 1
  483.     rep    movsw
  484.     rcl    cx, 1
  485.     rep    movsb
  486.  
  487.     pop    si            ; restore buffer pointer
  488.     pop    ds
  489.     pop    cx            ; restore buffer length
  490.     mov    bx, dx            ; restore handle
  491.  
  492.     mov    ax, 1            ; tell application copy completed
  493.     call    cs:[bx].hndReceive
  494.  
  495. rx5:    pop    bx            ; restore ucb pointer
  496.     pop    es
  497.  
  498. tx_upc:    mov    ax, dllDeallocate    ; free portal's RX buffer
  499.     int    dllInt
  500.     retf
  501.  
  502. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  503. ;; PKT Function:  not_implemented     ;;
  504. ;;  regs inp: none              ;;
  505. ;;  regs out: none              ;;
  506. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  507.  
  508. not_implemented:
  509.     mov    dh, pkterrBadCommand    ; return bad command error
  510.     jmp    bad
  511.  
  512. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  513. ;; PKT Function:  driver_info          ;;
  514. ;;  regs inp: none              ;;
  515. ;;  regs out: bx,ch,dx,cl,ds,si,al    ;;
  516. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  517.  
  518. driver_info:
  519.     mov    [bp]._al, pktFunction    ; return information in registers
  520.     mov    [bp]._ch, pktClass
  521.     mov    [bp]._dx, pktType
  522.     mov    [bp]._cl, pktNumber
  523.     mov    [bp]._bx, pktVersion
  524.     mov    [bp]._ds, cs
  525.     mov    [bp]._si, offset pktName
  526.     jmp    good
  527.  
  528. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  529. ;; PKT Function:  access_type          ;;
  530. ;;  regs inp: al,bx,dl,ds,si,cx,es,di ;;
  531. ;;  regs out: ax              ;;
  532. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  533.  
  534. access_type:
  535.     cmp    al, pktClass        ; verify class
  536.     je    acc1
  537.     mov    dh, pkterrNoClass
  538.     jmp    bad
  539.  
  540. acc1:    cmp    dl, pktNumber        ; verify number
  541.     je    acc2
  542.     mov    dh, pkterrNoNumber
  543.     jmp    bad
  544.  
  545. acc2:    cmp    cx, ethTypeLen        ; verify protocol type
  546.     je    acc3
  547.     mov    dh, pkterrBadType
  548.     jmp    bad
  549.  
  550. acc3:    mov    dx, [si]        ; save protocol type
  551.     cmp    dx, 0
  552.     je    acc8
  553.  
  554.     mov    ax, cs            ; address data segment
  555.     mov    ds, ax
  556.  
  557.     mov    si, offset hndTab    ; address handle table
  558. acc4:    cmp    word ptr [si].hndType, dx ; find matching handle
  559.     jne    acc5
  560.     cmp    [si].hndInUse, 1
  561.     je    acc7
  562.     jmp    short acc9
  563. acc5:    add    si, size HND
  564.     cmp    si, offset hndEnd
  565.     jb    acc4
  566.  
  567.     mov    si, offset hndTab    ; address handle table
  568. acc6:    cmp    word ptr [si].hndInUse, 0 ; find non-inuse non-perm handle
  569.     je    acc9
  570.     add    si, size HND
  571.     cmp    si, offset hndEnd
  572.     jb    acc6
  573.     mov    dh, pkterrNoSpace
  574.     jmp    bad
  575. acc7:    mov    dh, pkterrTypeInuse
  576.     jmp    bad
  577. acc8:    jmp    good
  578.  
  579. acc9:    mov    word ptr [si].hndType, dx ; store some handle data
  580.     mov    word ptr [si].hndReceive.segm, es
  581.     mov    word ptr [si].hndReceive.offs, di
  582.  
  583.     push    bp            ; save register pointer
  584.     sub    sp, size DCB        ; allocate DCB on stack
  585.     mov    ax, ss
  586.     mov    es, ax
  587.     mov    bx, sp
  588.     mov    bp, sp
  589.  
  590.     mov    ax, [si].hndPortalID    ; store handle and skip if open
  591.     mov    [bp].dcbPortalID, ax
  592.     cmp    [si].hndPerm, 1
  593.     jne    acc10
  594.     jmp    acc13
  595.  
  596. acc10:    mov    [bp].dcbBufferPtr.segm, cs ; get active portal list - C'mon Guys
  597.     mov    [bp].dcbBufferPtr.offs, offset pList
  598.     mov    [bp].dcbBufferLen, maxHandles * 2
  599.     mov    ax, dllReadPlist
  600.     int    dllInt
  601.  
  602.     mov    cx, [bp].dcbBufferLen    ; scan for match
  603.     mov    [bp].dcbBufferPtr.segm, cs
  604.     mov    [bp].dcbBufferPtr.offs, offset pStat
  605.     mov    [bp].dcbBufferLen, size PSB
  606.     mov    di, offset pList
  607. acc11:    mov    ax, [di]
  608.     add    di, 2
  609.     mov    word ptr [bp].dcbPortalID, ax
  610.     mov    ax, dllReadPortal
  611.     int    dllInt
  612.     mov    ax, dllerrPTinuse
  613.     cmp    dx, word ptr pStat.psbPtype
  614.     je    acc15
  615.     loop    acc11
  616.  
  617.     mov    [bp].dcbPad, dllNoPad    ; open portal
  618.     mov    [bp].dcbMode, dllModeDIX
  619.     cmp    dx, 3781h
  620.     jne    acc12
  621.     cmp    flag802, 1
  622.     jne    acc12
  623.     mov    [bp].dcbMode, dllMode802
  624.     mov    dx, -1
  625. acc12:    mov    word ptr [bp].dcbLScallback.segm, 0
  626.     mov    word ptr [bp].dcbLScallback.offs, 0
  627.     mov    word ptr [bp].dcbRXcallback.segm, cs
  628.     mov    word ptr [bp].dcbRXcallback.offs, offset rx_upc
  629.     mov    word ptr [bp].dcbTXcallback.segm, cs
  630.     mov    word ptr [bp].dcbTXcallback.offs, offset tx_upc
  631.     mov    word ptr [bp].dcbPType, dx
  632.     mov    ax, dllOpen
  633.     int    dllInt
  634.  
  635.     cmp    ax, dllerrSuccess    ; check for success
  636.     jne    acc15
  637.  
  638.     mov    ax, [bp].dcbPortalID    ; store portal ID
  639.     mov    [si].hndPortalID, ax
  640.  
  641. acc13:    cmp    word ptr [si].hndReceive.segm, 0 ; check for permanent flag
  642.     jne    acc14                 ; where es:bx = 0:0
  643.     cmp    word ptr [si].hndReceive.offs, 0
  644.     jne    acc14
  645.  
  646.     add    sp, size DCB        ; deallocate DCB
  647.     pop    bp            ; restore register pointer
  648.     mov    [si].hndPerm, 1        ; set permanent flag
  649.     jmp    good            ; done
  650.  
  651. acc14:    lea    di, [bp].dcbSaddr    ; enable broadcasts
  652.     mov    cx, ethAddrLen / 2
  653.     mov    ax, -1
  654.     rep    stosw
  655.     mov    ax, dllEnbMulti
  656.     int    dllInt
  657.  
  658.     add    sp, size DCB        ; deallocate DCB
  659.     pop    bp            ; restore register pointer
  660.  
  661.     mov    [si].hndInUse, 1    ; set in use flag
  662.     mov    [bp]._ax, si        ; return handle
  663.     jmp    good            ; done
  664.  
  665. acc15:    add    sp, size DCB        ; deallocate DCB
  666.     pop    bp            ; restore register pointer
  667.  
  668.     mov    dh, pkterrTypeInuse    ; protocol in use error
  669.     cmp    ax, dllerrPTinuse
  670.     je    acc16
  671.     mov    dh, pkterrNoSpace    ; all other errors
  672. acc16:    jmp    bad            ; done
  673.  
  674. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  675. ;; PKT Function:  release_type          ;;
  676. ;;  regs inp: bx              ;;
  677. ;;  regs out: none              ;;
  678. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  679.  
  680. release_type:
  681.     mov    ax, cs            ; address handle table
  682.     mov    ds, ax
  683.     mov    si, [bp]._bx        ; BX trashed by dispatcher
  684.  
  685.     cmp    si, offset hndTab    ; skip if too small
  686.     jb    rel2
  687.     cmp    si, offset hndEnd    ; skip if too large
  688.     jae    rel2
  689.     cmp    [si].hndInUse, 1    ; skip if not in use
  690.     jne    rel2
  691.  
  692.     sub    sp, size DCB        ; allocate DCB on stack
  693.     mov    ax, ss
  694.     mov    es, ax
  695.     mov    bx, sp
  696.  
  697.     mov    ax, [si].hndPortalID    ; store portal ID
  698.     mov    es:[bx].dcbPortalID, ax
  699.  
  700.     lea    di, [bx].dcbSaddr    ; disable broadcasts
  701.     mov    cx, ethAddrLen / 2
  702.     mov    ax, -1
  703.     rep    stosw
  704.     mov    ax, dllDisMulti
  705.     int    dllInt
  706.  
  707.     cmp    [si].hndPerm, 1        ; check for permanent handle
  708.     je    rel1
  709.  
  710.     mov    ax, dllClose        ; close portal
  711.     int    dllInt
  712.  
  713. rel1:    add    sp, size DCB        ; deallocate DCB
  714.  
  715.     cmp    ax, dllerrSuccess    ; check for success
  716.     jne    rel2
  717.  
  718.     mov    [si].hndInUse, 0    ; clear in use flag
  719.     jmp    good
  720.  
  721. rel2:    mov    dh, pkterrBadHandle    ; return bad handle error
  722.     jmp    bad
  723.  
  724. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  725. ;; PKT Function:  send_pkt          ;;
  726. ;;  regs inp: ds,si,cx              ;;
  727. ;;  regs out: none              ;;
  728. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  729.  
  730. send_pkt:
  731.     call    send            ; call send packet routine
  732.     jmp    good
  733.  
  734. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  735. ;; PKT Function:  terminate          ;;
  736. ;;  regs inp: bx              ;;
  737. ;;  regs out: none              ;;
  738. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  739.  
  740. terminate:
  741.     call    safe            ; check for windows or task switcher
  742.     jnz    term5
  743.  
  744.     mov    si, offset hndTab    ; address handle table
  745. term1:    cmp    cs:[si].hndInUse, 1    ; check for handles in use
  746.     je    term5
  747.     add    si, size HND
  748.     cmp    si, offset hndEnd
  749.     jb    term1
  750.  
  751.     xor    ax, ax            ; check for hooked vector
  752.     mov    ds, ax
  753.     mov    dx, cs
  754.     mov    bx, cs:pktVec
  755.     cmp    [bx].segm, dx
  756.     jne    term5
  757.     cmp    [bx].offs, offset intpkt
  758.     jne    term5
  759.  
  760.     sub    sp, size DCB        ; allocate DCB on stack
  761.     mov    ax, ss
  762.     mov    es, ax
  763.     mov    bx, sp
  764.  
  765.     mov    si, offset hndTab    ; address handle table
  766. term2:    cmp    cs:[si].hndPerm, 1    ; check for permanent handles
  767.     jne    term3
  768.     mov    ax, cs:[si].hndPortalID    ; free portal
  769.     mov    es:[bx].dcbPortalID, ax
  770.     mov    ax, dllClose
  771.     int    dllInt
  772. term3:    add    si, size HND
  773.     cmp    si, offset hndEnd
  774.     jb    term2
  775.  
  776.     mov    ax, dllStartMOP        ; re-enable MOP
  777.     int    dllInt
  778.     mov    ax, dllEnaMOPmulti
  779.     int    dllInt
  780.  
  781.     add    sp, size DCB        ; deallocate DCB
  782.  
  783.     mov    bx, cs:pktVec        ; restore vector
  784.     xor    ax, ax
  785.     cli
  786.     mov    [bx].segm, ax
  787.     mov    [bx].offs, ax
  788.     sti
  789.  
  790.     mov    ax, cs            ; address TSR memory
  791.     mov    es, ax
  792.  
  793.     cmp    ax, [bp]._cs        ; avoid releasing memory twice
  794.     je    term4            ; when calling itself
  795.  
  796.     mov    ah, 49h            ; release TSR memory
  797.     int    21h
  798. term4:    jmp    good
  799.  
  800. term5:    mov    dh, pkterrCantTerminate    ; return can't terminate error
  801.     jmp    bad
  802.  
  803. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  804. ;; PKT Function:  get_address          ;;
  805. ;;  regs inp: bx,es,di,cx          ;;
  806. ;;  regs out: cx              ;;
  807. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  808.  
  809. get_address:
  810.     cmp    cx, ethAddrLen        ; check buffer length
  811.     jnb    get1
  812.     mov    dh, pkterrNoSpace
  813.     jmp    bad
  814.  
  815. get1:    mov    ax, cs            ; copy ethernet address
  816.     mov    ds, ax
  817.     mov    si, offset ether
  818.     mov    cx, ethAddrLen / 2
  819.     rep    movsw
  820.     mov    [bp]._cx, ethAddrLen
  821.     jmp    good
  822.  
  823. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  824. ;; PKT Function:  reset_interface     ;;
  825. ;;  regs inp: bx              ;;
  826. ;;  regs out: none              ;;
  827. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  828.  
  829. reset_interface:
  830.     mov    dh, pkterrCantReset    ; return can't reset error
  831.     jmp    bad
  832.  
  833. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  834. ;; PKT Function:  stop_upcalls          ;;
  835. ;;  regs inp: none              ;;
  836. ;;  regs out: none              ;;
  837. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  838.  
  839. stop_upcalls:
  840.     mov    ax, cs            ; address handle table
  841.     mov    ds, ax
  842.  
  843.     sub    sp, size DCB        ; allocate DCB on stack
  844.     mov    ax, ss
  845.     mov    es, ax
  846.     mov    bx, sp
  847.  
  848.     mov    si, offset hndTab    ; address handle table
  849. stop1:    cmp    [si].hndInUse, 1    ; check for handle in use
  850.     jne    stop2
  851.  
  852.     mov    ax, [si].hndPortalID    ; store portal id
  853.     mov    es:[bx].dcbPortalID, ax
  854.  
  855.     lea    di, [bx].dcbSaddr    ; disable broadcasts
  856.     mov    cx, ethAddrLen / 2
  857.     mov    ax, -1
  858.     rep    stosw
  859.     mov    ax, dllDisMulti
  860.     int    dllInt
  861.  
  862.     cmp    [si].hndPerm, 1        ; check for permanent handle
  863.     je    stop2
  864.  
  865.     mov    ax, dllClose        ; close portal
  866.     int    dllInt
  867.  
  868. stop2:    mov    [si].hndInUse, 0    ; clear in use flag
  869.     add    si, size HND
  870.     cmp    si, offset hndEnd
  871.     jb    stop1
  872.  
  873.     add    sp, size DCB        ; deallocate DCB
  874.     jmp    good
  875.  
  876. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  877. ;; PKT Function:  get_parameters      ;;
  878. ;;  regs inp: none              ;;
  879. ;;  regs out: es,di              ;;
  880. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  881.  
  882. get_parameters:
  883.     mov    [bp]._es, cs        ; return parameter block address
  884.     mov    [bp]._di, offset param
  885.     jmp    good
  886.  
  887. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  888. ;; PKT Function:  as_send_pkt          ;;
  889. ;;  regs inp: ds,si,cx,es,di          ;;
  890. ;;  regs out: none              ;;
  891. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  892.  
  893. as_send_pkt:
  894.     call    send            ; call send packet routine
  895.  
  896.     mov    ds, [bp]._es        ; call application upcall
  897.     mov    si, [bp]._di
  898.     mov    es, [bp]._ds
  899.     mov    di, [bp]._si
  900.     xor    ax, ax
  901.     call    dword ptr [si]
  902.  
  903.     jmp    good
  904.  
  905. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  906. ;; Packet Driver Function Table          ;;
  907. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  908.  
  909. funTab    dw    not_implemented        ; 0
  910.     dw    driver_info        ; 1
  911.     dw    access_type        ; 2
  912.     dw    release_type        ; 3
  913.     dw    send_pkt        ; 4
  914.     dw    terminate        ; 5
  915.     dw    get_address        ; 6
  916.     dw    reset_interface        ; 7
  917.     dw    stop_upcalls        ; 8
  918.     dw    not_implemented        ; 9
  919.     dw    get_parameters        ; 10
  920.     dw    as_send_pkt        ; 11
  921. maxFun    equ    ($ - offset funTab) / 2
  922.  
  923. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  924. ;; Packet Driver Interrupt Routine    ;;
  925. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  926.  
  927. intpkt: jmp    short int1        ; skip signature
  928.     nop
  929.  
  930. sig    db    'PKT DRVR', 0
  931.  
  932. int1:    sti                ; enable interrupts
  933.     cld                ; set forward direction
  934.  
  935.     push    ax            ; save all registers - hmmph!
  936.     push    bx
  937.     push    cx
  938.     push    dx
  939.     push    si
  940.     push    di
  941.     push    bp
  942.     push    ds
  943.     push    es
  944.     
  945.     mov    bp, sp            ; address registers with BP
  946.  
  947.     and    [bp]._flags, not carry    ; set success status
  948.  
  949.     cmp    ah, maxFun        ; validate function request
  950.     jb    int2
  951.     xor    ah, ah
  952.  
  953. int2:    mov    bl, ah            ; call function
  954.     xor    bh, bh            ;  note that BP must be preserved
  955.     shl    bx, 1            ;  within the functions
  956.     jmp    cs:funTab[bx]
  957.  
  958. bad:    or    [bp]._flags, carry    ; set error status
  959.     mov    [bp]._dh, dh
  960.  
  961. good:    pop    es            ; restore registers - hmmph!
  962.     pop    ds
  963.     pop    bp
  964.     pop    di
  965.     pop    si
  966.     pop    dx
  967.     pop    cx
  968.     pop    bx
  969.     pop    ax
  970.     iret
  971.  
  972. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  973. ;; Discardable PKT and DLL Init Code  ;;
  974. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  975.  
  976. start:    cld
  977.  
  978.     mov    dx, offset message    ; print copyright message
  979.     mov    ah, 9
  980.     int    21h
  981.  
  982.     call    safe            ; check for windows or task switcher
  983.     jz    parse
  984.     mov    dx, offset unsafe    ; print unsafe error and exit
  985.     mov    al, doserrError
  986.     jmp    exit
  987.  
  988. ; Parse Command Line
  989. parse:    mov    bp, offset cmdBuf + 1    ; address command line buffer
  990.     mov    si, offset proto    ; address protocol type list
  991.  
  992. parse1:    call    space            ; parse command line
  993.     call    number
  994.     jc    parse4
  995.  
  996.     cmp    ax, 60h            ; check if driver vector
  997.     jb    parse2
  998.     cmp    ax, 7fh
  999.     ja    parse2
  1000.  
  1001.     add    ax, ax            ; store driver vector
  1002.     add    ax, ax
  1003.     mov    pktVec, ax
  1004.     jmp    parse1
  1005.  
  1006. parse2:    cmp    ax, 00000h        ; check if protocol type
  1007.     je    parse3
  1008.     cmp    ax, 005efh
  1009.     jb    parse6
  1010.     cmp    ax, 0fffeh
  1011.     ja    parse6
  1012.  
  1013. parse3:    xchg    al, ah            ; store protocol type
  1014.     mov    [si], ax
  1015.     add    si, 2
  1016.     mov    word ptr [si], 0
  1017.     jmp    parse1
  1018.  
  1019. parse4:    call    space            ; check for switches
  1020.     cmp    al, cr
  1021.     je    check
  1022.     mov    bx, ax            ; save switch
  1023.  
  1024.     add    bp, 2            ; check end of line
  1025.     call    space
  1026.     cmp    al, cr
  1027.     jne    parse5
  1028.  
  1029.     or    ah, 20h            ; validate switches
  1030.     cmp    bx, "n/"
  1031.     je    novell
  1032.     cmp    bx, "s/"
  1033.     je    stop
  1034.     cmp    bx, "u/"
  1035.     je    term
  1036.  
  1037. parse5:    mov    dx, offset usage    ; print usage error and exit
  1038.     mov    al, doserrUsage
  1039.     jmp    exit
  1040.  
  1041. parse6:    mov    dx, offset range    ; print range error and exit
  1042.     mov    al, doserrRange
  1043.     jmp    exit
  1044.  
  1045. ; Terminate Packet Driver
  1046. term:    call    exist            ; check for existing driver
  1047.     mov    dx, offset missing
  1048.     mov    al, doserrError
  1049.     jne    trm1
  1050.  
  1051.     mov    ah, pktTerminate    ; call packet driver to terminate
  1052.     pushf
  1053.     call    dword ptr es:[bx]
  1054.  
  1055.     mov    dx, offset termin    ; print success and exit
  1056.     mov    al, doserrSuccess
  1057.     jnc    trm1
  1058.  
  1059.     mov    dx, offset active    ; print fail and exit
  1060.     mov    al, doserrError
  1061.  
  1062. trm1:    jmp    exit
  1063.  
  1064. ; Stop Packet Driver Upcalls
  1065. stop:    call    exist            ; check for existing driver
  1066.     mov    dx, offset missing
  1067.     mov    al, doserrError
  1068.     jne    stp1
  1069.  
  1070.     mov    ah, pktStopUpcalls    ; call packet driver to terminate
  1071.     pushf
  1072.     call    dword ptr es:[bx]
  1073.  
  1074.     mov    dx, offset stopped    ; print success and exit
  1075.     mov    al, doserrSuccess
  1076.  
  1077. stp1:    jmp    exit
  1078.  
  1079. ; Set Novell Netware 802.3 Flag
  1080. novell:    mov    flag802, 1
  1081.  
  1082. ; Perform Pre-Install Checks
  1083. check:    call    exist            ; check for existing driver
  1084.     mov    dx, offset already
  1085.     mov    al, doserrExists
  1086.     je    check1
  1087.  
  1088.     mov    dx, offset inuse    ; check for null vectors
  1089.     mov    al, doserrError
  1090.     cmp    es:[bx].segm, 0
  1091.     jne    check1
  1092.     cmp    es:[bx].offs, 0
  1093.     jne    check1
  1094.  
  1095.     mov    bx, schInt * 4        ; check for DLL
  1096.     les    bx, es:[bx]
  1097.     mov    dx, offset no_dll
  1098.     mov    al, doserrError
  1099.     cmp    byte ptr es:[bx]-3, 'S'
  1100.     jne    check1
  1101.     cmp    byte ptr es:[bx]-2, 'C'
  1102.     jne    check1
  1103.     cmp    byte ptr es:[bx]-1, 'H'
  1104.     jne    check1
  1105.  
  1106.     mov    ax, dllInsCheck
  1107.     int    dllInt
  1108.     cmp    ax, dllerrNotImpl
  1109.     mov    al, doserrError
  1110.     je    setup
  1111.  
  1112. check1:    jmp    exit            ; print error and exit
  1113.  
  1114. ; Setup and Start Packet Driver
  1115. setup:    push    ds            ; save data segment
  1116.     sub    sp, size DCB        ; allocate DCB on stack
  1117.     mov    ax, ss
  1118.     mov    es, ax
  1119.     mov    bx, sp
  1120.  
  1121.     mov    ds, ax            ; address ethernet address buffer
  1122.     lea    si, [bx].dcbSaddr
  1123.  
  1124.     mov    ax, dllReadChan        ; get ethernet address
  1125.     int    dllInt
  1126.  
  1127.     mov    ax, cs            ; copy ethernet address
  1128.     mov    es, ax
  1129.     mov    di, offset ether
  1130.     mov    cx, ethAddrLen / 2
  1131.     rep    movsw
  1132.  
  1133.     mov    ax, dllStopMOP        ; disable MOP
  1134.     int    dllInt
  1135.  
  1136.     add    sp, size DCB        ; deallocate DCB
  1137.     pop    ds            ; restore data segment
  1138.  
  1139.     xor    ax, ax            ; get hardware interrupt vector
  1140.     mov    es, ax
  1141.     mov    bx, schInt * 4
  1142.     mov    ax, es:[bx].segm
  1143.  
  1144.     mov    bx, hd1Int * 4 + 4    ; scan 1st bank skipping the timer
  1145.     mov    cx, 7
  1146. setup1:    cmp    ax, es:[bx].segm
  1147.     je    setup3
  1148.     add    bx, 4
  1149.     loop    setup1
  1150.  
  1151.     mov    bx, hd2Int * 4        ; scan 2nd bank
  1152.     mov    cx, 8
  1153. setup2:    cmp    ax, es:[bx].segm
  1154.     je    setup3
  1155.     add    bx, 4
  1156.     loop    setup2
  1157.  
  1158.     mov    bx, 0            ; clear if no match
  1159. setup3:    shr    bx, 1            ; store interrupt vector
  1160.     shr    bx, 1
  1161.     mov    param.prmIntNum, bx
  1162.  
  1163.     mov    bx, pktVec        ; setup up interrupt vectors
  1164.     cli
  1165.     mov    es:[bx].segm, cs
  1166.     mov    es:[bx].offs, offset intpkt
  1167.     sti
  1168.  
  1169.     push    es:[bx].segm        ; hold open protocol types for Windows
  1170.     push    es:[bx].offs        ; special permanent flag: es:di = 0:0
  1171.     mov    bp, sp
  1172.  
  1173.     xor    di, di            ; initialize registers
  1174.     mov    si, offset proto
  1175.     mov    cx, ethTypeLen
  1176.     mov    dl, pktNumber
  1177.     mov    bx, pktType
  1178.     mov    al, pktClass
  1179.     mov    ah, pktAccessType
  1180.  
  1181. setup4:    cmp    word ptr [si], 0    ; address protocol types
  1182.     je    setup6
  1183.  
  1184.     pushf                ; call packet driver to open
  1185.     call    dword ptr [bp]
  1186.     inc    si
  1187.     inc    si
  1188.     jnc    setup4
  1189.  
  1190.     mov    ah, pktTerminate    ; call packet driver to terminate
  1191.     mov    al, dh
  1192.     pushf
  1193.     call    dword ptr [bp]
  1194.     add    sp, 4            ; clean up stack
  1195.  
  1196.     mov    dx, offset ptinuse    ; print failure message and exit
  1197.     cmp    al, pkterrTypeInuse
  1198.     je    setup5
  1199.     mov    dx, offset nospace
  1200. setup5:    mov    al, doserrError
  1201.     jmp    short exit
  1202.  
  1203. setup6:    add    sp, 4            ; clean up stack
  1204.  
  1205. ; Print Message and Become Resident
  1206. ;
  1207. tsr:    mov    dx, offset install    ; print success message
  1208.     mov    ah, 9
  1209.     int    21h
  1210.  
  1211.     mov    es, envSeg        ; free environment space
  1212.     mov    ah, 49h
  1213.     int    21h
  1214.     mov    envSeg, 0
  1215.  
  1216.     mov    cx, 5            ; close all standard file handles
  1217.     xor    bx, bx
  1218. tsr1:    mov    ah, 3eh
  1219.     int    21h
  1220.     inc    bx
  1221.     loop    tsr1
  1222.  
  1223.     mov    dx, offset start    ; terminate and stay resident
  1224.     add    dx, 0fh
  1225.     mov    cl, 4
  1226.     shr    dx, cl
  1227.     mov    ax, 3100h
  1228.     int    21h
  1229.  
  1230. ; Print Message and Terminate
  1231. ;
  1232. exit:    push    ax            ; print message
  1233.     mov    ah, 9
  1234.     int    21h
  1235.     pop    ax
  1236.  
  1237.     mov    ah, 4ch            ; terminate with status
  1238.     int    21h
  1239.  
  1240. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1241. ;; Discardable Init Code Subroutines  ;;
  1242. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1243.  
  1244. space:    cmp    byte ptr [bp], ' '    ; skip spaces and tabs
  1245.     je    space1
  1246.     cmp    byte ptr [bp], tab
  1247.     je    space1
  1248.     mov    ax, word ptr [bp]
  1249.     ret
  1250. space1:    inc    bp
  1251.     jmp    short space
  1252.  
  1253. number:    xor    ax, ax            ; clear number
  1254.     mov    cx, -1
  1255.  
  1256.     cmp    word ptr [bp], 'x0'    ; remove prefix if any
  1257.     je    num1
  1258.     cmp    word ptr [bp], 'X0'
  1259.     je    num1
  1260.     jmp    short num2
  1261. num1:    xor    cx, cx
  1262.     add    bp, 2
  1263.  
  1264. num2:    mov    bl, byte ptr [bp]    ; validate digit
  1265.     cmp    bl, '0'
  1266.     jb    num5
  1267.     cmp    bl, '9'
  1268.     ja    num4
  1269.  
  1270. num3:    xor    cx, cx            ; add digit
  1271.     mov    dx, 10h
  1272.     mul    dx
  1273.     cmp    dx, 0
  1274.     jnz    num6
  1275.     sub    bl, '0'
  1276.     xor    bh, bh
  1277.     add    ax, bx
  1278.     inc    bp
  1279.     jmp    num2
  1280.  
  1281. num4:    or    bl, 20h            ; check for hex
  1282.     cmp    bl, 'a'
  1283.     jb    num5
  1284.     cmp    bl, 'f'
  1285.     ja    num5
  1286.     sub    bl, 'a' - '9' - 1
  1287.     jmp    num3
  1288.  
  1289. num5:    cmp    cx, 0            ; skip if no number entered
  1290.     jnz    num7
  1291.  
  1292.     mov    bl, byte ptr [bp]    ; ok if space, tab, switch or return
  1293.     cmp    bl, ' '
  1294.     je    num7
  1295.     cmp    bl, tab
  1296.     je    num7
  1297.     cmp    bl, '/'
  1298.     je    num7
  1299.     cmp    bl, cr
  1300.     je    num7
  1301.  
  1302.     mov    dx, offset usage    ; print usage error and exit
  1303.     mov    al, doserrUsage
  1304.     jmp    exit
  1305.  
  1306. num6:    mov    dx, offset range    ; number out of range
  1307.     mov    al, doserrRange
  1308.     jmp    exit
  1309.  
  1310. num7:    add    cx, 1
  1311.     ret
  1312.  
  1313. exist:    xor    ax, ax            ; check for existing driver
  1314.     mov    es, ax
  1315.     mov    bx, pktVec
  1316.  
  1317.     push    es
  1318.     les    di, es:[bx]
  1319.     add    di, 3
  1320.     mov    si, offset sig
  1321.     mov    cx, 9
  1322.     rep    cmpsb
  1323.     pop    es
  1324.     ret
  1325.  
  1326. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1327. ;; Discardable Init Code Data          ;;
  1328. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1329.  
  1330. message    db    'PKTDLL 1.2'                            ,eol
  1331.     db    '(c) Copyright Brian Angus 1993.  All rights reserved.'        ,eol
  1332.     db    'This software is provided with NO WARRANTY.'        ,eol,eos
  1333. install    db    'PKTDLL is installed and ready.'                ,eos
  1334. termin    db    'PKTDLL successfully unloaded.'                    ,eos
  1335. stopped    db    'PKTDLL upcalls stopped.'                    ,eos
  1336. usage    db    'Usage: PKTDLL [packet_int] [proto_type...] [/n] [/s] [/u].',eos
  1337. range    db    'Specified values are out of range (0, 60-7F, 05EF-FFFE).'  ,eos
  1338. no_dll    db    'Please start the DLL driver first.'                ,eos
  1339. already    db    'A driver is already installed at this vector.'            ,eos
  1340. inuse    db    'Specified interrupt is already in use.'            ,eos
  1341. nospace    db    'Not enough portals for requested protocols.'            ,eol
  1342.     db    'Unload some protocols (ie. LAT, LAST, etc.)'            ,eos
  1343. ptinuse    db    'Protocol type(s) are already in use.'                ,eol
  1344.     db    'Check specified and/or default protocols.'            ,eos
  1345. missing    db    'PKTDLL is not loaded at specified vector.'            ,eos
  1346. active    db    'Cannot unload PKTDLL - protocols still active.'        ,eos
  1347. unsafe    db    'Cannot load or unload PKTDLL in this environment.'        ,eos
  1348. proto    dw    0008h, 0608h, 3580h, 0000h
  1349.  
  1350. CODE    ends
  1351.     end    at100h
  1352.