IPXREAL.ASM 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. ;
  2. ; Copyright 2020 Electronic Arts Inc.
  3. ;
  4. ; TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
  5. ; software: you can redistribute it and/or modify it under the terms of
  6. ; the GNU General Public License as published by the Free Software Foundation,
  7. ; either version 3 of the License, or (at your option) any later version.
  8. ; TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
  9. ; in the hope that it will be useful, but with permitted additional restrictions
  10. ; under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
  11. ; distributed with this program. You should have received a copy of the
  12. ; GNU General Public License along with permitted additional restrictions
  13. ; with this program. If not, see [https://github.com/electronicarts/CnC_Remastered_Collection]>.
  14. ;***************************************************************************
  15. ;** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
  16. ;***************************************************************************
  17. ;* *
  18. ;* Project Name : VQLIB *
  19. ;* *
  20. ;* File Name : HANDLER.ASM *
  21. ;* *
  22. ;* Programmer : Bill Randolph *
  23. ;* *
  24. ;* Start Date : April 7, 1995 *
  25. ;* *
  26. ;* Last Update : April 7, 1995 [BRR] *
  27. ;* *
  28. ;*-------------------------------------------------------------------------*
  29. ;* Functions: *
  30. ;* IPXHandler -- callback routine for IPX *
  31. ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
  32. ;********************* Model & Processor Directives ************************
  33. IDEAL
  34. MODEL LARGE
  35. P386N
  36. LOCALS ??
  37. ;******************************** Includes *********************************
  38. ;******************************** Defines ***********************************
  39. ;****************************** Declarations ********************************
  40. GLOBAL IPXHandler:FAR
  41. ;********************************* Code ************************************
  42. CODESEG
  43. ;---------------------------------------------------------------------------
  44. ; The markers let the application verify that it's mapping this memory
  45. ; correctly.
  46. ;---------------------------------------------------------------------------
  47. Marker1 DW 1111h ; placeholder to find data start
  48. ;---------------------------------------------------------------------------
  49. ; This is the IPX Event Control Block:
  50. ;---------------------------------------------------------------------------
  51. ECB_LinkAddress DD ?
  52. ECB_EventServiceRoutine DD ? ; Event Handler ptr
  53. ECB_InUse DB ? ; 0 = event is complete
  54. ECB_CompletionCode DB ? ; 0 = OK, IPX error otherwise
  55. ECB_SocketNumber DW ? ; socket to listen/send on
  56. ECB_ConnectionID DW ?
  57. ECB_RestOfWorkspace DW ?
  58. ECB_DriverWorkSpace DB 12 DUP (?)
  59. ECB_ImmediateAddress DB 6 DUP (?) ; bridge address
  60. ECB_PacketCount DW ? ; # data areas (2)
  61. ECB_HeaderAddress DD ? ; ptr to IPX header buffer
  62. ECB_HeaderLength DW ? ; length of IPX header buffer
  63. ECB_PacketAddress DD ? ; ptr to packet buffer
  64. ECB_PacketLength DW ? ; length of packet buffer
  65. ;---------------------------------------------------------------------------
  66. ; The rest of the variables are for telling IPX which buffer to store the
  67. ; next incoming packet in. They must be initialized by the application.
  68. ;---------------------------------------------------------------------------
  69. NumBufs DW 0 ; # buffers provided by app
  70. BufferFlags DD 0 ; array of in-use flags (1 = in use)
  71. PacketSize DW 0 ; total size of 1 buf (incl IPX hdr)
  72. FirstPacketBuf DD 0 ; ptr to 1st packet buffer
  73. CurIndex DW 0 ; current packet/flag index
  74. CurPacketBuf DD 0 ; ptr to current packet buf
  75. FuncOffset DW StartLabel ; offset of our routine
  76. ;---------------------------------------------------------------------------
  77. ; These values are for preventing re-entrancy; they're currently not used.
  78. ;---------------------------------------------------------------------------
  79. Semaphore DB 0 ; prevents re-entrancy
  80. ReEntrantCount DW 0 ; times we've been called re-entrantly
  81. ;---------------------------------------------------------------------------
  82. ; Local stack space
  83. ;---------------------------------------------------------------------------
  84. StackPtr DW 0 ; saved copy of stack ptr
  85. StackSeg DW 0 ; saved copy of stack seg
  86. StackPtr_int DW 0 ; our internal stack ptr
  87. StackSeg_int DW 0 ; our internal stack seg
  88. StackCheck DW 1234h ; check for stack overflow
  89. DW 256 DUP (0) ; stack storage space
  90. StackSpace DW 0 ; label for our stack space
  91. ;---------------------------------------------------------------------------
  92. ; These bytes mark the end of the real-mode data area
  93. ;---------------------------------------------------------------------------
  94. Marker2 DW 2222h ; placeholder to find data end
  95. ;***************************************************************************
  96. ;* IPXHandler -- IPX callback routine *
  97. ;* *
  98. ;* This routine is assembled as a stand-alone executable, then loaded *
  99. ;* into low DOS memory by a protected-mode application. *
  100. ;* *
  101. ;* INPUT: *
  102. ;* none. *
  103. ;* *
  104. ;* OUTPUT: *
  105. ;* none. *
  106. ;* *
  107. ;* WARNINGS: *
  108. ;* none. *
  109. ;* *
  110. ;* HISTORY: *
  111. ;* 04/07/1995 BRR : Created. *
  112. ;*=========================================================================*
  113. label StartLabel
  114. PROC IPXHandler C FAR USES
  115. ;...................................................................
  116. ; Turn off interrupts; make sure memory copies go forward
  117. ;...................................................................
  118. pushf
  119. cli
  120. cld
  121. ;...................................................................
  122. ; Set up segment registers to point DS to CS
  123. ;...................................................................
  124. push ds
  125. push ax
  126. mov ax,cs
  127. mov ds,ax
  128. ;...................................................................
  129. ; Set up our local stack; save SS & SP first.
  130. ;...................................................................
  131. mov [StackSeg],ss
  132. mov [StackPtr],sp
  133. mov [StackPtr_int], OFFSET StackSpace
  134. mov [StackSeg_int], SEG StackSpace
  135. lss sp, [DWORD PTR StackPtr_int]
  136. ;...................................................................
  137. ; Save all registers
  138. ;...................................................................
  139. pushad
  140. push es
  141. ;...................................................................
  142. ; If we've been called re-entrantly, just exit
  143. ;...................................................................
  144. cmp [Semaphore],0
  145. jz ??Start_Handler
  146. add [ReEntrantCount],1
  147. jmp ??Exit_Handler
  148. ??Start_Handler:
  149. ;...................................................................
  150. ; Set our semaphore
  151. ;...................................................................
  152. mov [Semaphore],1
  153. ;-------------------------------------------------------------------
  154. ; Set 'CurIndex' to the index of the next-available receive buffer,
  155. ; and 'CurPacketBuf to the next-available packet buffer
  156. ;-------------------------------------------------------------------
  157. ;...................................................................
  158. ; Get 'CurIndex' & increment it. Wrap to 0 if we reach 'NumBufs'
  159. ; Since I'm treating 'CurPacketBuf' as a long integer (and not as
  160. ; a segment:offset), the entire data area can't be larger than 64K.
  161. ;...................................................................
  162. mov dx,[CurIndex] ; DX = CurIndex
  163. mov eax,[CurPacketBuf] ; EAX = current packet buffer addr
  164. inc dx ; DX = next index
  165. add ax,[PacketSize] ; EAX = next buffer ptr
  166. cmp dx,[NumBufs] ; see if DX is past # buffers
  167. jb ??Get_Flag
  168. mov dx,0 ; wrap to 1st index
  169. mov eax,[FirstPacketBuf] ; wrap to 1st packet buffer
  170. ??Get_Flag:
  171. ;...................................................................
  172. ; Get the next buffer-in-use flag; if it's 0, load [CurIndex] with
  173. ; the value of SI (the next index). If it's 1, skip the updating of
  174. ; the index, flag & buffer ptr.
  175. ; DX = new CurIndex
  176. ; EAX = new CurPacketBuf
  177. ;...................................................................
  178. les di,[BufferFlags] ; ES:DI = BufferFlags address
  179. mov bx,di ; BX = DI + new CurIndex
  180. add bx,dx
  181. cmp [BYTE PTR es:bx],0 ; compare next flag to 0 (avail)
  182. jne ??Set_ECB ; if not avail, skip setting new values
  183. ;...................................................................
  184. ; The next buffer is available; so, set this buffer's In-Use flag
  185. ; to 1, and move on to the next buffer. Do not set this buffer's
  186. ; flag to 1 until we move on to the next buffer, to prevent the
  187. ; application from reading the currently-in-use packet buffer.
  188. ; DX = new CurIndex
  189. ; EAX = new CurPacketBuf
  190. ; ES:DI = BufferFlags address
  191. ;...................................................................
  192. mov bx,di ; BX = DI + old CurIndex
  193. add bx,[CurIndex]
  194. mov [BYTE PTR es:bx],1 ; set old BufferFlags value to in-use
  195. mov [CurIndex],dx ; save new index
  196. mov [CurPacketBuf],eax ; save new packet address
  197. ;-------------------------------------------------------------------
  198. ; Set up the Event Control Block to tell IPX to start listening.
  199. ; The following entries are filled in by the app, and should be left
  200. ; alone:
  201. ; - EventServiceRoutine
  202. ; - SocketNumber
  203. ; The rest should be re-initialized. Note that EBX is now pointing
  204. ; to an unavailable buffer if the next buffer was already in use;
  205. ; so it must be reloaded with the correct buffer address from
  206. ; [CurPacketBuf].
  207. ;-------------------------------------------------------------------
  208. ??Set_ECB:
  209. mov [ECB_LinkAddress],0 ; default
  210. mov [ECB_InUse],0 ; default
  211. mov [ECB_CompletionCode],0 ; default
  212. mov [ECB_ConnectionID],0 ; default
  213. mov [ECB_RestOfWorkspace],0 ; default
  214. mov [ECB_DriverWorkSpace],0 ; default
  215. mov [ECB_ImmediateAddress],0 ; default
  216. mov [ECB_PacketCount],2 ; use 2 data areas
  217. mov ebx,[CurPacketBuf] ; get current buffer address
  218. mov [ECB_HeaderAddress],ebx ; set header address
  219. mov [ECB_HeaderLength],30 ; size of IPX header
  220. add ebx,30 ; point to past the header
  221. mov [ECB_PacketAddress],ebx ; set packet data address
  222. mov ax,[PacketSize] ; get size of one buffer
  223. sub ax,30 ; remove size of IPX header
  224. mov [ECB_PacketLength],ax ; set size of packet data
  225. ;-------------------------------------------------------------------
  226. ; Clear the IPX header for this packet
  227. ;-------------------------------------------------------------------
  228. les di,[ECB_HeaderAddress] ; ES:DI = IPX Listen Header
  229. mov cx,30 ; (30 bytes = size of header)
  230. mov al,0
  231. rep stosb ; clear to 0's
  232. ;-------------------------------------------------------------------
  233. ; Command IPX to start listening again.
  234. ;-------------------------------------------------------------------
  235. mov bx,4 ; IPX code for Listen
  236. mov ax,ds ; ES = segment of ListenECB
  237. mov es,ax
  238. mov ax,OFFSET ECB_LinkAddress
  239. mov si,ax ; ES:SI = address of ECB
  240. int 07ah ; call IPX interrupt
  241. ;...................................................................
  242. ; Clear our semaphore
  243. ;...................................................................
  244. mov [Semaphore],0
  245. ??Exit_Handler:
  246. ;...................................................................
  247. ; Pop values from our local stack
  248. ;...................................................................
  249. pop es
  250. popad
  251. ;...................................................................
  252. ; Check our stack-check value; if the stack has overflowed, generate
  253. ; a debugger break.
  254. ;...................................................................
  255. cmp [StackCheck],1234h
  256. je ??Restore_Stack
  257. int 3
  258. ;...................................................................
  259. ; Restore the stack to its previous value
  260. ;...................................................................
  261. ??Restore_Stack:
  262. lss sp, [DWORD PTR StackPtr]
  263. ;...................................................................
  264. ; Pop the rest of the registers
  265. ;...................................................................
  266. pop ax
  267. pop ds
  268. popf
  269. ret
  270. ENDP IPXHandler
  271. END
  272. ;************************** End of handler.asm *****************************