Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

558 lines
12 KiB

  1. ;/* himem5.asm
  2. ; *
  3. ; * Microsoft Confidential
  4. ; * Copyright (C) Microsoft Corporation 1988-1991
  5. ; * All Rights Reserved.
  6. ; *
  7. ; * Modification History
  8. ; *
  9. ; * Sudeepb 14-May-1991 Ported for NT XMS support
  10. ; */
  11. page 95,160
  12. title himem5.asm - Extended Memory Moves
  13. ;
  14. ;----------------------------------------------------------------------------
  15. ;
  16. ; M001 : inserted a jmp $+2 between an out & in while reading the ISR
  17. ; M003 : fixed bug to do with not returning int 15h errors on a blockmove
  18. ; call.
  19. ;
  20. ;----------------------------------------------------------------------------
  21. ;
  22. .xlist
  23. include himem.inc
  24. include xmssvc.inc
  25. include vint.inc
  26. .list
  27. extrn TopOfTextSeg:word
  28. extrn hiseg:word
  29. extrn pReqHdr:dword
  30. extrn dd_int_loc:word
  31. extrn interrupt:word
  32. extrn fInHMA:byte
  33. extrn EndText:byte
  34. ifdef NEC_98
  35. extrn InHMAMsg:byte
  36. endif ;NEC_98
  37. _text ends
  38. funky segment word public 'funky'
  39. assume cs:funky
  40. extrn KiddValley:word
  41. extrn KiddValleyTop:word
  42. extrn end_of_hiseg:word
  43. extrn textseg:word
  44. extrn LEnblA20:dword
  45. extrn LDsblA20:dword
  46. extrn FunkyCLI:near
  47. extrn FunkySTI:near
  48. ;******************************************************************************
  49. ;
  50. ; MoveBlock
  51. ; XMM Move Extended Memory Block
  52. ;
  53. ; Entry:
  54. ; ES:SI Points to structure containing:
  55. ; bCount dd ? ; Length of block to move
  56. ; SourceHandle dw ? ; Handle for souce
  57. ; SourceOffset dd ? ; Offset into source
  58. ; DestHandle dw ? ; Handle for destination
  59. ; DestOffset dd ? ; Offset into destination
  60. ;
  61. ; Return:
  62. ; AX = 1 Success
  63. ; AX = 0 Failure
  64. ; Error code in BL
  65. ;
  66. ; Registers Destroyed:
  67. ; Flags
  68. ;
  69. ;------------------------------------------------------------------------------
  70. public MoveBlock
  71. MoveBlock proc far
  72. assume ds:_text
  73. call FunkySTI ; Be nice
  74. push bp ; Set up stack frame so we
  75. mov bp, sp ; can have local variables
  76. sub sp, 18 ; Space for local variables
  77. ; Following Ordering is used in xms.dll and should be retained
  78. ; as is or changed in both places.
  79. Count = -4 ; Local DWORD for byte count
  80. SrcLinear = -8
  81. DstLinear = -12
  82. MEReturn = -14 ; Local WORD for return code
  83. SrcHandle = -16
  84. DstHandle = -18
  85. push bx
  86. push dx
  87. xor ax, ax
  88. mov [bp.MEReturn], ax ; Assume success
  89. mov [bp.SrcHandle], ax
  90. mov [bp.DstHandle], ax
  91. mov ax, word ptr es:[si].bCount ; Pick up length specified
  92. mov word ptr [bp.Count], ax
  93. mov cx, word ptr es:[si].bCount+2
  94. mov word ptr [bp.Count+2], cx
  95. or cx, ax
  96. jcxz MEM2_Exit ; Exit immediately if zero
  97. lea bx, [si].SourceHandle ; Normalize Source
  98. call GetLinear ; Linear address in DX:AX
  99. jc MEM2_SrcError ; Have Dest Error Code
  100. mov word ptr [bp.SrcLinear], ax ; Save Linear address
  101. mov word ptr [bp.SrcLinear+2], dx
  102. mov [bp.SrcHandle], bx ; Save Handle for Unlock
  103. lea bx, [si].DestHandle ; Normalize Destination
  104. call GetLinear
  105. jc MEM2_Error
  106. mov word ptr [bp.DstLinear], ax ; Save Linear address
  107. mov word ptr [bp.DstLinear+2], dx
  108. mov [bp.DstHandle], bx ; Save Handle for Unlock
  109. shr word ptr [bp.Count+2], 1 ; Make word count
  110. rcr word ptr [bp.Count], 1
  111. jc MEM2_InvCount ; Odd count not allowed
  112. call LEnblA20
  113. cmp ax, 1
  114. jne MEM2_Error
  115. XMSSVC XMS_MOVEBLOCK ; Call Worker
  116. ; Parameters on the stack
  117. call LDSblA20
  118. cmp ax, 1
  119. jne MEM2_Error
  120. MEM2_Exit:
  121. mov bx, [bp.SrcHandle] ; Unlock Handles if necessary
  122. or bx, bx
  123. jz NoSrcHandle
  124. dec [bx].cLock ; Unlock Source
  125. NoSrcHandle:
  126. mov bx, [bp.DstHandle]
  127. or bx, bx
  128. jz NoDstHandle
  129. dec [bx].cLock ; Unlock Destination
  130. NoDstHandle:
  131. pop dx
  132. pop bx
  133. mov ax, 1
  134. cmp word ptr [bp.MEReturn], 0
  135. jz MEM2_Success
  136. dec ax
  137. mov bl, byte ptr [bp.MEReturn]
  138. MEM2_Success:
  139. mov sp, bp ; Unwind stack
  140. pop bp
  141. ret
  142. MEM2_SrcError:
  143. cmp bl, ERR_LENINVALID ; Invalid count
  144. je MEM2_Error ; yes, no fiddle
  145. sub bl, 2 ; Convert to Source error code
  146. jmp short MEM2_Error
  147. MEM2_InvCount:
  148. mov bl, ERR_LENINVALID
  149. MEM2_Error:
  150. mov byte ptr [bp.MEReturn], bl ; Pass error code through
  151. jmp short MEM2_Exit
  152. MoveBlock endp
  153. ;*******************************************************************************
  154. ;
  155. ; GetLinear
  156. ; Convert Handle and Offset (or 0 and SEG:OFFSET) into Linear address
  157. ; Locks Handle if necessary
  158. ;
  159. ; Entry:
  160. ; ES:BX Points to structure containing:
  161. ; Handle dw
  162. ; Offset dd
  163. ; [BP.Count] Count of bytes to move
  164. ;
  165. ; Return:
  166. ; BX Handle of block (0 if conventional)
  167. ; AX:DX Linear address
  168. ; CARRY => Error
  169. ; Error code in BL
  170. ;
  171. ; Registers Destroyed:
  172. ; Flags, CX, DI
  173. ;
  174. ;-------------------------------------------------------------------------------
  175. GetLinear proc near
  176. push si
  177. call FunkyCLI ; NO INTERRUPTS
  178. mov si, word ptr es:[bx+2] ; Offset from start of handle
  179. mov di, word ptr es:[bx+4] ; in DI:SI
  180. mov bx, word ptr es:[bx] ; Handle in bx
  181. or bx, bx
  182. jz GL2_Conventional
  183. test [bx].Flags, USEDFLAG ; Valid Handle?
  184. jz GL2_InvHandle
  185. mov ax, [bx].Len ; Length of Block
  186. mov cx, 1024
  187. mul cx ; mul is faster
  188. sub ax, si
  189. sbb dx, di ; DX:AX = max possible count
  190. jc GL2_InvOffset ; Base past end of block
  191. sub ax, word ptr [bp.Count]
  192. sbb dx, word ptr [bp.Count+2]
  193. jc GL2_InvCount ; Count too big
  194. inc [bx].cLock ; Lock the Handle
  195. mov ax, [bx].Base
  196. mul cx
  197. add ax, si ; Linear address
  198. adc dx, di ; in DX:AX
  199. GL2_OKExit:
  200. clc
  201. GL2_Exit:
  202. call FunkySTI
  203. pop si
  204. ret
  205. GL2_Conventional:
  206. mov ax, di ; Convert SEG:OFFSET into
  207. mov dx, 16 ; 24 bit address
  208. mul dx
  209. add ax, si
  210. adc dx, 0 ; DX:AX has base address
  211. mov di, dx
  212. mov si, ax
  213. add si, word ptr [bp.Count] ; Get End of Block + 1 in DI:SI
  214. adc di, word ptr [bp.Count+2]
  215. cmp di, 010h ; Make sure it doesn't wrap
  216. ja GL2_InvCount ; past the end of the HMA
  217. jb GL2_OKExit
  218. cmp si, 0FFF0h
  219. jbe GL2_OKExit ; Must be < 10FFF0h
  220. GL2_InvCount:
  221. mov bl, ERR_LENINVALID
  222. jmp short GL2_Error
  223. GL2_InvHandle:
  224. mov bl, ERR_DHINVALID ; Dest handle invalid
  225. jmp short GL2_Error
  226. GL2_InvOffset:
  227. mov bl, ERR_DOINVALID ; Dest Offset invalid
  228. GL2_Error:
  229. stc
  230. jmp short GL2_Exit
  231. GetLinear endp
  232. ;*----------------------------------------------------------------------*
  233. ;* *
  234. ;* pack_and_truncate - packs everything down into the *
  235. ;* lowest available memory and sets up variable for driver *
  236. ;* truncation, then terminates. *
  237. ;* *
  238. ;*----------------------------------------------------------------------*
  239. ifdef NEC_98
  240. HMALen dw ? ; Length of funky (without init code)
  241. endif ;NEC_98
  242. public pack_and_truncate
  243. pack_and_truncate proc far
  244. assume ds:_text,es:nothing
  245. push ds
  246. mov dx, offset _text:EndText ; end of text seg
  247. add dx, 15
  248. and dx, not 15 ; size of text seg including init code
  249. mov ax, TopOfTextSeg ; end of resident text seg
  250. or ax, ax
  251. jnz @f
  252. xor di, di
  253. pop es
  254. jmp short InitFailed
  255. @@:
  256. add ax, 15
  257. and ax, not 15 ; size of resident text seg
  258. sub dx, ax ; size of memory whole between
  259. shr dx, 4 ; resident text seg and funky seg
  260. ; The funky seg should be moved down
  261. ; 'dx' number of paragraphs
  262. mov ax, hiseg ; Get the current seg at which funky
  263. ; is running from
  264. cmp ax, dx ; If funky is already running from a
  265. ; segment value less than 'dx'
  266. ; number of paras funky can be
  267. ; moved to zero segment only
  268. jbe @f
  269. mov ax, dx ; ax has min of seg of funky
  270. ; & memory whole size in para
  271. @@:
  272. or ax, ax ; if funky is to be moved by zero
  273. ; paras our job is over
  274. jnz @f
  275. mov es, hiseg
  276. assume es:funky
  277. mov di, es:KiddValleyTop
  278. jmp NoMoveEntry
  279. @@:
  280. mov dx, hiseg ; current segment value of funky
  281. push ds
  282. pop es
  283. assume es:_text
  284. mov ds, dx ; which is our source for move
  285. assume ds:nothing
  286. sub dx, ax ; less the 'paras' to be shrinked
  287. mov hiseg, dx ; is the new seg value of funky
  288. mov es, dx ; which is our dest. for the move
  289. assume es:nothing
  290. mov si, HISEG_ORG
  291. mov di, si
  292. mov cx, end_of_hiseg
  293. sub cx, si ; size of funky without ORG
  294. cld
  295. rep movsb ; move it!!!
  296. ;;
  297. MoveHandleTable:
  298. inc di ; round to word value
  299. and di,0fffeh
  300. mov si,di
  301. assume es:funky
  302. xchg si,es:KiddValley ; replace KiddValley with new location
  303. mov cx,es:KiddValleyTop
  304. sub cx,si
  305. rep movsb ; move the handle table down
  306. mov es:KiddValleyTop,di ; update end of table
  307. assume es:nothing
  308. NoMoveEntry:
  309. pop ds ; restore _text segment
  310. assume ds:_text
  311. add di,15 ; round new segment to paragraph
  312. and di,not 15
  313. ifndef NEC_98
  314. InitFailed:
  315. ifdef debug_tsr
  316. mov ax,ds ; # paragraphs to keep =
  317. mov dx,es ; (ES - DS) +
  318. sub dx,ax ; (DI >> 4) +
  319. mov ax,di ; 10h
  320. shr ax,4
  321. add dx,ax
  322. add dx,10h ; PSP size
  323. mov ax,3100h
  324. int 21h
  325. else
  326. lds si,[pReqHdr] ; discard the initialization code
  327. mov word ptr ds:[si].Address[0],di
  328. mov word ptr ds:[si].Address[2],es
  329. mov ds:[si].Status,100h ; Store return code - DONE
  330. pop ax ; throw away return from InitDriver
  331. push cs
  332. call an_iret ; call an iret in our segment
  333. or di, di
  334. jz we_are_quitting
  335. mov ds, textseg
  336. assume ds:_text
  337. mov ax, hiseg
  338. mov dd_int_loc,offset Interrupt ; replace Interrupt with
  339. ; tiny permanent stub
  340. mov ax, KiddValleyTop
  341. sub ax, KiddValley
  342. add ax, end_of_hiseg
  343. sub ax, HISEG_ORG ; size of resident funky including
  344. mov cs:HMALen, ax
  345. mov ax, ((multMULT shl 8)+multMULTGETHMAPTR)
  346. xor bx, bx ; in case there is no HMA handler
  347. int 2fh
  348. cmp cs:HMALen, bx
  349. ja we_are_quitting
  350. cmp di, HISEG_ORG
  351. ja we_are_quitting
  352. mov bx, cs:HMALen
  353. mov ax, ((multMULT shl 8)+multMULTALLOCHMA)
  354. int 2fh
  355. cmp di, 0ffffh
  356. je we_are_quitting
  357. call MoveHi
  358. we_are_quitting:
  359. pop bp
  360. pop si
  361. pop di
  362. pop es
  363. pop ds
  364. pop dx
  365. pop cx
  366. pop bx
  367. pop ax
  368. ret ; far return from driver init
  369. endif
  370. else ;NEC_98
  371. ifdef debug_tsr
  372. mov dx,di
  373. shr dx,4 ; get # paragraphs to retain
  374. mov ax,3100h
  375. int 21h
  376. else
  377. InitFailed:
  378. lds si,[pReqHdr] ; discard the initialization code
  379. mov word ptr ds:[si].Address[0],di
  380. mov word ptr ds:[si].Address[2],es
  381. mov ds:[si].Status,100h ; Store return code - DONE
  382. pop ax ; throw away return from InitDriver
  383. push cs
  384. call an_iret ; call an iret in our segment
  385. or di, di
  386. jz we_are_quitting
  387. mov ds, textseg
  388. assume ds:_text
  389. mov ax, hiseg
  390. mov dd_int_loc,offset Interrupt ; replace Interrupt with
  391. ; tiny permanent stub
  392. mov ax, KiddValleyTop
  393. sub ax, KiddValley
  394. add ax, end_of_hiseg
  395. sub ax, HISEG_ORG ; size of resident funky including
  396. mov HMALen, ax
  397. mov ax, ((multMULT shl 8)+multMULTGETHMAPTR)
  398. int 2fh
  399. cmp HMALen, bx
  400. ja we_are_quitting
  401. cmp di, HISEG_ORG
  402. ja we_are_quitting
  403. mov bx, HMALen
  404. mov ax, ((multMULT shl 8)+multMULTALLOCHMA)
  405. int 2fh
  406. cmp di, 0ffffh
  407. je we_are_quitting
  408. call MoveHi
  409. we_are_quitting:
  410. pop bp
  411. pop si
  412. pop di
  413. pop es
  414. pop ds
  415. pop dx
  416. pop cx
  417. pop bx
  418. pop ax
  419. ret ; far return from driver init
  420. endif
  421. endif ;NEC_98
  422. pack_and_truncate endp
  423. ifndef NEC_98
  424. HMALen dw ? ; Length of funky (without init code)
  425. endif ;NEC_98
  426. ;
  427. ;---------------------------------------------------------------------------
  428. ;
  429. ; procedure : MoveHi
  430. ;
  431. ;---------------------------------------------------------------------------
  432. ;
  433. MoveHi proc near
  434. push di ; remember offset in HMA
  435. mov si, HISEG_ORG
  436. ifndef NEC_98
  437. mov cx, cs:HMALen
  438. else ;NEC_98
  439. mov cx, HMALen
  440. endif ;NEC_98
  441. mov ax, textseg
  442. mov ds, ax
  443. assume ds:_text
  444. mov ds, hiseg
  445. assume ds:nothing
  446. rep movsb ; move it to HMA
  447. pop di ; get back offset in HMA
  448. mov ax, HISEG_ORG
  449. sub ax, di
  450. shr ax, 1
  451. shr ax, 1
  452. shr ax, 1
  453. shr ax, 1
  454. mov bx, es
  455. sub bx, ax
  456. mov ax, textseg
  457. mov ds, ax ; get addressability to text seg
  458. assume ds:_text
  459. mov fInHMA, 1 ; Flag that we are running from HMA
  460. mov hiseg, bx
  461. mov es, bx
  462. mov di, TopOfTextSeg ; end of resident text code
  463. mov ax, textseg
  464. lds si, pReqHdr
  465. assume ds:nothing
  466. mov word ptr ds:[si].Address[0],di
  467. mov word ptr ds:[si].Address[2],ax
  468. ret
  469. MoveHi endp
  470. ;
  471. an_iret proc near
  472. FIRET
  473. an_iret endp
  474. public end_of_funky_seg
  475. end_of_funky_seg:
  476. funky ends
  477. end
  478.