INT2F.A86
上传用户:xiaogehua
上传日期:2007-01-08
资源大小:1183k
文件大小:29k
源码类别:

操作系统开发

开发平台:

Asm

  1. ;    File              : $Workfile$
  2. ;
  3. ;    Description       :
  4. ;
  5. ;    Original Author   : 
  6. ;
  7. ;    Last Edited By    : $Author$
  8. ;
  9. ;-----------------------------------------------------------------------;
  10. ;    Copyright Work of Caldera, Inc. All Rights Reserved.
  11. ;      
  12. ;    THIS WORK IS A COPYRIGHT WORK AND CONTAINS CONFIDENTIAL,
  13. ;    PROPRIETARY AND TRADE SECRET INFORMATION OF CALDERA, INC.
  14. ;    ACCESS TO THIS WORK IS RESTRICTED TO (I) CALDERA, INC. EMPLOYEES
  15. ;    WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF
  16. ;    THEIR ASSIGNMENTS AND (II) ENTITIES OTHER THAN CALDERA, INC. WHO
  17. ;    HAVE ACCEPTED THE CALDERA OPENDOS SOURCE LICENSE OR OTHER CALDERA LICENSE
  18. ;    AGREEMENTS. EXCEPT UNDER THE EXPRESS TERMS OF THE CALDERA LICENSE
  19. ;    AGREEMENT NO PART OF THIS WORK MAY BE USED, PRACTICED, PERFORMED,
  20. ;    COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED,
  21. ;    CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
  22. ;    TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF
  23. ;    CALDERA, INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT
  24. ;    AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND
  25. ;    CIVIL LIABILITY.
  26. ;-----------------------------------------------------------------------;
  27. ;
  28. ;    *** Current Edit History ***
  29. ;    *** End of Current Edit History ***
  30. ;
  31. ;    $Log$
  32. ;    INT2F.A86 1.23 94/11/14 10:34:17
  33. ;    Fixed the NWDOS.386 stuff. Still point at startupinfo, but take out the
  34. ;    vxdname and the vxdnameseg entries.
  35. ;    INT2F.A86 1.22 94/10/07 09:05:11
  36. ;    Added patch 005 as source fix. Removed the stuff to load NWDOS.386 as
  37. ;    the vxd is no longer needed.
  38. ;    INT2F.A86 1.21 94/03/24 18:40:10
  39. ;    Support para-aligned HMA allocations (Stacker 4 bug)    
  40. ;    INT2F.A86 1.20 93/09/28 19:43:12
  41. ;    Extra field to export upper memory root on windows startup
  42. ;    INT2F.A86 1.19 93/09/06 15:37:35
  43. ;    Startup Broadcast fills entry ES:BX into SwStartupInfo "next" link field
  44. ;    INT2F.A86 1.16 93/08/06 16:35:58
  45. ;    Change DELWATCH int 2F hook for getnblk to getblk
  46. ;    INT2F.A86 1.15 93/07/20 22:47:21
  47. ;    Pass on Int 2F/12FF to BIOS - (really to CONFIG)
  48. ;    INT2F.A86 1.11 93/06/11 02:10:01
  49. ;    GateA20 disabled on EXEC for EXEPACKED apps
  50. ;    ENDLOG
  51. ;
  52. ;   DOS INT 2F Support
  53. ;
  54. include pcmode.equ
  55. include i:msdos.equ
  56. include i:mserror.equ
  57. include i:driver.equ
  58. include i:psp.def
  59. include i:doshndl.def
  60. include i:redir.equ
  61. PCM_CODE CSEG BYTE
  62. extrn get_dseg:near ; in PCMIF.PCM
  63. extrn do_int24:near ; in PCMIF.PCM
  64. extrn dos_entry:near
  65. extrn strlen:near ; in SUPPORT.PCM
  66. extrn toupper:near ; in UTILS.FDO (in BDOS_CODE)
  67. extrn ReadTOD:near ; in UTILS.FDO (in BDOS_CODE)
  68. extrn share_delay:near ; in UTILS.FDO (in BDOS_CODE)
  69. eject
  70. PointHMA:
  71. ;--------
  72. ; On Entry:
  73. ; None
  74. ; On Exit:
  75. ; DS = DOS data seg
  76. ; BX = bytes available (0 if none)
  77. ; ES:DI -> start of available area (FFFF:FFFF if none)
  78. ; All other regs preserved
  79. ;
  80. call get_dseg ; DS = DOS data
  81. mov di,0FFFFh
  82. mov es,di ; ES:DI = FFFF:FFFF
  83. mov bx,hmaRoot
  84. test bx,bx ; have we an HMA ?
  85.  jz PointHMA10
  86. mov di,bx ; ES:DI = start of HMA free area
  87. mov bx,es:2[bx] ; BX = length
  88. sub bx,4 ; forget the header
  89. and bl,not 15 ; make it complete para's
  90. PointHMA10:
  91. ret
  92. QueryHMA:
  93. ;--------
  94. ; On Entry:
  95. ; None
  96. ; On Exit:
  97. ; BX = bytes available (0 if none)
  98. ; ES:DI -> start of available area (FFFF:FFFF if none)
  99. ; All other regs preserved
  100. ;
  101. push ds
  102. call PointHMA ; registers ready for return
  103. jmps int2F_BIOS ; give CONFIG processing a chance
  104. AllocHMA:
  105. ;--------
  106. ; On Entry:
  107. ; BX = bytes required
  108. ; On Exit:
  109. ; ES:DI -> start of available area (FFFF:FFFF if none)
  110. ;
  111. push ds
  112. xchg ax,bx ; AX = bytes required
  113. add ax,15
  114. and al,not 15 ; round up to para's
  115. call PointHMA
  116. xchg ax,bx
  117. cmp ax,bx ; enough room up there ?
  118.  jae AllocHMA10
  119. mov di,es ; ES:DI = FFFF:FFFF
  120. jmps AllocHMA20
  121. AllocHMA10:
  122. add hmaRoot,bx ; set new start
  123. mov ax,es:2[di] ; get length
  124. sub ax,bx ; subtract what we just allocated
  125. mov es:2[di+bx],ax ; set new length
  126. cmp ax,4 ; have we shrunk to zero spare ?
  127. mov ax,es:[di] ; move link field to
  128. mov es:[di+bx],ax ;  new head
  129.  ja AllocHMA20
  130. mov hmaRoot,ax ; set new hmaRoot
  131. AllocHMA20:
  132. mov ax,4A02h ; "restore" AX
  133. pop ds
  134. iret
  135. eject
  136. ; ++++++++++++++++++++++++++++
  137. ; Int 2F - Multiplex Interrupt
  138. ; ++++++++++++++++++++++++++++
  139. ;
  140. ; This interrupt is used by DBASE III Plus
  141. ;
  142. ; On Entry:-    AH - Multi-Plex Number
  143. ; 01 -  Print Spooler
  144. ; 02 - Assign Command (Documented)
  145. ; 05 - Critical Error Msg
  146. ; 06 - Assign Command (By Inspection)
  147. ; 08 - DRIVER.SYS Interface for MS-DOS 3.xx
  148. ; 10 - Share Command
  149. ; 11 - Internal DOS - Network Hooks
  150. ; 12 - Internal DOS - Support Services
  151. ; 13 - Original INT 13 ROS ISR Address (BIOS)
  152. ; 14 - NLSFUNC utility
  153. ; AD - IBM CodePage Screen Driver
  154. ; B7 - Append Command
  155. ; B8 - Network Command
  156. ;
  157. ; AL - Function Code
  158. ; 00 -  Get Installed State (All)
  159. ; 01 - Submit File (PRINT)
  160. ; 02 - Cancel File (PRINT)
  161. ; 03 - Cancel All Files (PRINT)  
  162. ; 04 - Spooler Status (PRINT)
  163. ; 05 - End of Status (PRINT)
  164. ;
  165. ; The Network Test returns the current Network configuration in
  166. ; BX when the Get Installed State is requested.
  167. ;
  168. ; BX = 0008h Redirector | Increasing
  169. ; BX = 0080h Receiver |  Network
  170. ; BX = 0004h Messenger |      Functionality
  171. ; BX = 0040h Server V
  172. ;
  173. Public int2F_entry
  174. int2F_entry:
  175. sti
  176. cld
  177. cmp ah,012h ! je i2f_12 ; intercept the AH=12 subfunctions
  178. cmp ah,011h ! je i2f_11 ; intercept the AH=11 subfunctions
  179. cmp ah,010h ! je i2f_10 ; intercept the AH=10 subfunctions
  180. cmp ah,005h ! je i2f_05 ; intercept the AH=05 subfunctions
  181. cmp ax,4A01h! je QueryHMA ; intercept Query Free HMA Space
  182. cmp ax,4A02h! je AllocHMA ; intercept Allocate HMA space
  183. cmp ah,016h ! jne int2F_exit ; intercept the AH=16 subfucntions
  184. jmp WindowsHooks ; go do windows things...
  185. int2F_exit:
  186. push ds ; pass onto BIOS now
  187. call get_dseg ; trying to remain ROMMABLE
  188. int2F_BIOS:
  189. jmpf ds:int2FNext ;  hence this complication
  190. eject
  191. i2f_05:
  192. ;------
  193. ; CRITICAL ERROR MSG
  194. ; This is the critical error message interceptor.
  195. ; On Entry: AL = extended error code.
  196. ; On Exit:  if CY clear then ES:DI -> ASCIIZ string to be used in place
  197. ;  of the default error message
  198. stc ; please use the default message
  199. retf 2 ; IRET, but keep flags
  200. eject
  201. i2f_10:
  202. ;------
  203. ; SHARE
  204. cmp al,i2f_10size ; do we do this one ?
  205.  jae int2F_exit ;  no, skip it
  206. shl al,1 ; we need a word offset
  207.  jz int2F_exit ;  exit if share installation check
  208. cbw ; zero AH
  209. xchg ax,bx ; we will index with it
  210. push ds
  211. call get_dseg ; get PCMode data seg
  212. push ds ! pop es
  213. call i2f_10tbl[bx] ; execute the function
  214. pop ds
  215. retf 2 ;  and return
  216. eject
  217. i2f_11:
  218. ;------
  219. ; MSNET redirector
  220. test al,al ; is it installation check ?
  221.  jz i2f_11_10
  222. mov ax,1 ; no, return ED_FUNCTION error
  223. stc ; indicate an error
  224. i2f_11_10:
  225. retf 2 ; return
  226. eject
  227. i2f_12:
  228. ;------
  229. ; DOS Internal
  230. ; Support DOS internal functions here
  231. cmp al,0FFh ; should we pass it on to the BIOS ?
  232.  je int2F_exit ; yes, do so
  233. cmp al,i2f_12size ; do we do this one ?
  234.  jae i2f_12_bad ;  no, skip it
  235. push bp
  236. xor ah,ah
  237. add ax,ax ; make sub-func a word
  238. mov bp,ax ; we need offset in pointer register
  239. mov ax,i2f_12tbl[bp] ; get address of service routine
  240. mov bp,sp ; BP points to stack frame
  241. call ax ; call the service routine
  242. pop bp
  243. i2f_12_exit:
  244. retf 2 ; IRET, but returning flags
  245. i2f_12_bad:
  246. mov ax,-ED_FUNCTION
  247. stc
  248. retf 2
  249. i2f_12tbl dw i2f_1200
  250. dw i2f_1201
  251. dw i2f_1202
  252. dw i2f_1203
  253. dw i2f_1204
  254. dw i2f_1205
  255. dw i2f_1206
  256. dw i2f_12nyi ; Move disk buffer
  257. dw i2f_1208
  258. dw i2f_12nyi ; DS:DI -> Disk Buffer ??
  259. dw i2f_120A
  260. dw i2f_120B
  261. dw i2f_120C
  262. dw i2f_120D
  263. if DOS5
  264. dw share_delay ; delay
  265. else
  266. dw i2f_120E ; get buffers
  267. endif
  268. dw i2f_12nyi ; relink buffer ES:DI ([DI+5].20 <- 0) - Trout
  269. dw i2f_1210
  270. dw i2f_1211
  271. dw i2f_1212
  272. dw i2f_1213
  273. dw i2f_1214
  274. dw i2f_12nyi ; Disk buffer DS:SI ??? (Write - Trout)
  275. dw i2f_1216
  276. dw i2f_1217
  277. dw i2f_1218
  278. dw i2f_1219
  279. dw i2f_121A
  280. dw i2f_121B
  281. dw i2f_121C
  282. dw i2f_121D
  283. dw i2f_121E
  284. dw i2f_121F
  285. dw i2f_1220
  286. dw i2f_1221
  287. dw i2f_1222
  288. dw i2f_1223
  289. dw share_delay
  290. dw i2f_1225
  291. dw i2f_1226
  292. dw i2f_1227
  293. dw i2f_1228
  294. dw i2f_1229
  295. dw i2f_122A
  296. dw i2f_122B
  297. dw i2f_122C
  298. dw i2f_122D
  299. i2f_12size equ ((offset $) - (offset i2f_12tbl))/2
  300. i2f_12nyi:
  301. ; Sets CY the falls through to installation check - so returns ax = 00FF
  302. ; Who knows what to do ?
  303. stc ; indicate problem ?
  304. i2f_1200:
  305. mov ax,00FFh
  306. ret
  307. i2f_1201:
  308. ; Close file ??? (at current_dhndl)
  309. les di,current_dhndl
  310. mov bx,es:DHNDL_WATTR[di]
  311. test bh,DHAT_REMOTE/100h
  312.  jz i2f_1201_10 ; is it networked ?
  313. mov ax,I2F_CLOSE
  314. int 2fh ; then close using int 2f call
  315. i2f_1201_10: ; else do nothing for now
  316. ret
  317. i2f_1202:
  318. ; Get Interrupt Vector pointer
  319. xor bx,bx
  320. mov es,bx ; point at the vectors
  321. mov bl,8[bp] ; pick up which vector
  322. add bx,bx
  323. add bx,bx ; make it a DWORD offset
  324. ret
  325. i2f_1203:
  326. ; Get DOS Data segment
  327. jmp get_dseg ; return DS = DOS data seg
  328. i2f_1204:
  329. ; Normalise path character
  330. mov ax,8[bp] ; the char is on the stack
  331. tobslash:
  332. cmp al,'/' ; if it's a fslash
  333.  jne i2f_1204_10
  334. mov al,'' ;  make it a bslash
  335. i2f_1204_10:
  336. cmp al,'' ; set ZF if bslash
  337. ret
  338. i2f_1205:
  339. ; Output Character on the stack
  340. push dx
  341. mov ah,MS_C_WRITE
  342. mov dx,8[bp] ; get char from the stack
  343. call dos_entry ;  and output it
  344. pop dx
  345. ret
  346. i2f_1206:
  347. ; Invoke critical error INT 24
  348. push ds
  349. mov ax,8[bp] ; action/drive on stack
  350. mov es,0[bp] ; seg was in BP
  351. call get_dseg ; get the segment right
  352. call do_int24 ; invoke the critical error handler
  353. push ax
  354.     les ax,int24_esbp       
  355. mov [bp],ax ; really return new BP
  356. pop ax
  357. pop ds
  358. ret
  359. i2f_1208:
  360. ; Decrement word at ES:DI, skipping zero
  361. mov ax,es:word ptr [di] ; return the word in AX
  362. i2f_1208_10:
  363. dec es:word ptr [di] ; dec it
  364.  jz i2f_1208_10 ;  dec again if it's zero
  365. ret
  366. i2f_120A:
  367. push ds
  368. lds si,current_ddsc ; point at current driver
  369. lodsb ; get the drive
  370. cbw ; pretend dos area read
  371. pop ds
  372. mov err_drv,al
  373. mov rwmode,ah ; set error drive for Int 24h
  374. mov ax,3 ; return a Fail ?
  375. stc ; return as error
  376. ret
  377. i2f_120B:
  378. ; ES:DI -> system file table entry
  379. mov ax,20h ; sharing violation
  380. stc ; return as error
  381. ret
  382. i2f_120C:
  383. ; Open file ??? (at current_dhndl)
  384. les di,current_dhndl
  385. ; would need to call the device driver, but as we don't support this for
  386. ; block devices and as it is generally not supported for remote files (but
  387. ; only known to be called from redirectors) we leave this out for later
  388. test es:byte ptr DHNDL_MODE+1[di],DHM_FCB/100h
  389.  jz i2f_120C_10 ; is it an FCB open ?
  390. mov ax,current_psp
  391. mov es:DHNDL_PSP[di],ax ; update owning PSP field
  392. i2f_120C_10: ; else do nothing for now
  393. ret
  394. i2f_120D:
  395. ; Get Date/Time
  396. push ds
  397. push es
  398. push cx
  399. push bx
  400. push si
  401. push di
  402. push ss
  403. pop ds
  404. call ReadTOD
  405. pop di
  406. pop si
  407. pop bx
  408. pop cx
  409. pop es
  410. pop ds
  411. ret
  412. if DOS5 eq 0
  413. i2f_120E:
  414. ; Disk Buffers
  415. ; On Return ES:DI -> first disk buffer
  416. ;
  417. les di,ss:bcb_root ; get head of buffer chain
  418. ret
  419. endif
  420. i2f_1210:
  421. ; Find Dirty Buffer Entry DS:SI -> 1st buffer, On exit DS:SI-> 1st dirty buffer
  422. ; ZF set if none found
  423. xor ax,ax ; never find dirty buffers
  424. ret
  425. i2f_1211:
  426. ; Normalise ASCIIZ filename DS:SI -> source buffer, ES:DI -> dest buffer
  427. ; make uppercase, fslash becomes bslash
  428. ; (Stops at slash - Trout)
  429. lodsb ; get a character
  430. call toupper ; upper case it
  431. call tobslash ; convert '/' to ''
  432. stosb ; plant it
  433. test al,al ; terminating zero ?
  434.  jnz i2f_1211
  435. mov ax,8[bp] ; AX from stack
  436. ret
  437. i2f_1212:
  438. ; Get length of ASCIIZ string ES:DI
  439. push ds ! push si
  440. push es ! pop ds
  441. mov si,di ; make DS:SI -> ASCIIZ
  442. call i2f_1225 ;  then use our other primitive
  443. pop si ! pop ds
  444. ret
  445. i2f_1213:
  446. ; Upperase character on stack
  447. mov ax,8[bp] ; get the character
  448. jmp toupper ; use BDOS Intl routine
  449. i2f_1214:
  450. ; Compare far pointers DS:SI with ES:DI
  451. cmp di,si
  452.  jne i2f_1214_10
  453. push ax ! push bx
  454. mov ax,ds
  455. mov bx,es
  456. cmp ax,bx
  457. pop bx ! pop ax
  458. i2f_1214_10:
  459. ret
  460. i2f_1216:
  461. ; Get address in ES:DI of DOSHNDL for file BX
  462. push ds
  463. call get_dseg ; we work with the PCMODE data
  464. les di,file_ptr ; get the address of the first entry
  465. pop ds
  466. push bx ; handle # in BX
  467. i2f_1216_10:
  468. cmp bx,es:DCNTRL_COUNT[di] ; handle in this block?
  469.  jb i2f_1216_20 ; skip if yes
  470. sub bx,es:DCNTRL_COUNT[di] ; update the internal file number
  471. les di,es:DCNTRL_DSADD[di] ; get the next entry and check
  472. cmp di,0FFFFh ;   for the end of the list
  473.  jnz i2f_1216_10 
  474. pop ax ; handle # back in AX
  475. stc ; invalid file handle number
  476. ret
  477. i2f_1216_20:
  478. push dx ; save DX and calculate the offset
  479. mov ax,DHNDL_LEN ;   of the DOS Handle
  480. mul bx
  481. add di,ax ; add structure offset (should be 0) 
  482. add di,DCNTRL_LEN ;    and then skip the header
  483. pop dx
  484. pop ax ; handle # back in AX
  485. ; clc
  486. ret ; valid file handle number
  487. i2f_1217:
  488. ; Default Drive ???
  489. ; On Exit:
  490. ; AL = drive we have set to, DS:SI -> LDT structure
  491. call get_dseg ; DS -> PCMODE data
  492. mov ax,8[bp] ; get the drive
  493. cmp al,last_drv ; do we have an LDT for it ?
  494.  jae i2f_1217_10 ; if not do no more
  495. cmp word ptr ldt_ptr+2,0 ; valid LDT ?
  496.  je i2f_1217_10
  497. push ax
  498. mov ah,LDT_LEN
  499. mul ah
  500. lds si,ldt_ptr
  501. add si,ax ; DS:SI -> requested LDT, current_LDT
  502. mov ss:word ptr current_ldt,si
  503. mov ss:word ptr current_ldt+2,ds
  504. pop ax
  505. stc ; indicate NO error (CY inverted)
  506. i2f_1217_10:
  507. cmc
  508. ret ; CY set if invalid
  509. i2f_1218:
  510. ; DS:SI -> User register on DOS Call
  511. call get_dseg ; we save SS:SP after PUSH$DOS
  512. lds si,int21regs_ptr ;  in this location
  513. ret
  514. i2f_1219:
  515. ; Stack = drive (0=default, 1 = A: etc)
  516. push ds ! push si ! push word ptr 8[bp]
  517. dec byte ptr 8[bp] ; make drive zero based
  518. cmp byte ptr 8[bp],0ffh ; do we want the default ?
  519.  jne i2f_1219_10
  520. call get_dseg
  521. mov al,current_dsk
  522. mov byte ptr 8[bp],al ; use the default drive
  523. i2f_1219_10:
  524. call i2f_1217 ; set's up current_ldt
  525.  jc i2f_1219_20
  526. test ds:byte ptr 44h[si],40h ; is it valid LDT ?
  527.  jnz i2f_1219_20
  528. stc ; indicate an error
  529. i2f_1219_20:
  530. pop word ptr 8[bp] ! pop si ! pop ds
  531. ret
  532. i2f_121A:
  533. ; Get files drive DS:SI -> drives, AL = drive
  534. xor ax,ax ; assume default drive
  535. cmp ds:byte ptr 1[si],':'
  536.  jne i2f_121A_10 ; if no drive letter, then default
  537. mov al,ds:byte ptr [si]
  538. test al,al ; null string ?
  539.  jz i2f_121A_10 ;  then it's the default drive
  540. call toupper
  541. sub al,'A'-1 ; make one based
  542.  jbe i2f_121A_20 ; it's invalid..
  543. push ds
  544. call get_dseg
  545. cmp al,last_drv ; is it a valid drive ?
  546. pop ds
  547.  ja i2f_121A_20 ; yes, return it
  548. i2f_121A_10:
  549. clc
  550. ret
  551. i2f_121A_20:
  552. mov al,0FFh ; invalid drive
  553. stc
  554. ret
  555. i2f_121B:
  556. ; On Entry CX = year-1980
  557. ; On Exit AL = days in February
  558. push bx
  559. mov bx,offset days_in_month+1
  560. mov ds:byte ptr [bx],28 ; assume 28 days in Feb
  561. test cl,3 ; is it a leap year ?
  562.  jnz i2f_121B_10
  563. inc ds:byte ptr [bx] ; yes, we have 29
  564. i2f_121B_10:
  565. mov yearsSince1980,cl ; save the year
  566. mov al,ds:byte ptr [bx] ; return the days in Feb
  567. pop bx
  568. ret
  569. i2f_121C:
  570. ; Checksum Memory CX bytes at DS:SI, DX = initial checksum
  571. ; DX = final checksum
  572. ; I've seen this used to total days in N months.
  573. ; On Entry:
  574. ; CX = current month
  575. ; DX = total days in prior years
  576. ; DS:SI -> days-per-month table
  577. ; On Exit:
  578. ; DX = Total days to start of current month
  579. ;
  580. xor ax,ax ; clear AX
  581. jcxz i2f_121C_20 ; check for zero bytes
  582. i2f_121C_10:
  583. lodsb ; get a byte
  584. add dx,ax ; add to the checksum
  585. loop i2f_121C_10 ; until we run out
  586. i2f_121C_20:
  587. ret
  588. i2f_121D:
  589. ; Calculate Date
  590. ; On Entry:
  591. ; CX = 0
  592. ; DX = total day count this year
  593. ; DS:SI -> days-per-month table
  594. ; On Exit:
  595. ; CX = Month
  596. ; DX = Day
  597. ;
  598. xor ax,ax
  599. i2f_121D_10:
  600. lodsb
  601. inc cx
  602. sub dx,ax
  603.  jnb i2f_121D_10
  604. dec cx ; undo the last count
  605. add dx,ax ; undo the sub
  606. cmp dx,ax ; get the flags right
  607. ret
  608. i2f_121E:
  609. ; Compare Filenames at DS:SI and ES:DI
  610. push si ! push di ! push cx
  611. call i2f_1225 ; find length of DS:SI filename
  612. push cx
  613. call i2f_1212 ; find length of ES:DI filename
  614. pop ax
  615. cmp ax,cx ; if lengths not the same
  616.  jne i2f_121E_20 ;  don't even bother
  617. i2f_121E_10:
  618. push cx
  619. lodsb
  620. call toupper
  621. call tobslash ; normalise slash characters
  622. push ax ; save it
  623. mov al,es:byte ptr [di]
  624. inc di
  625. call toupper
  626. call tobslash ; normalise slash again
  627. pop cx ; recover the character
  628. cmp al,cl ; are they the same?
  629. pop cx
  630. loope i2f_121E_10 ; yes, try again if we have any left
  631. i2f_121E_20:
  632. pop cx ! pop di ! pop si
  633. mov ax,8[bp] ; return stack value in AX
  634. ret
  635. i2f_121F:
  636. ; Build drive info into block
  637. ; Stack = Drive (1=A: etc)
  638. push ds ! push si ! push dx
  639. call get_dseg
  640. les di,current_ldt
  641. push di
  642. mov ax,8[bp] ; get the drive we want to do
  643. stosb ; plant the ASCII
  644. xchg ax,dx ; save drive in DX
  645. mov ax,':'
  646. stosw ; we have d:
  647. xor ax,ax
  648. mov cx,LDT_FLAGS-3
  649. rep stosb ; zero rest of name and flags
  650. ; lea di,LDT_FLAGS
  651. and dl,1fh ; convert from ASCII
  652. dec dx ; into zero based drive number
  653. cmp dl,phys_drv ; valid physical drive ?
  654.  jae i2f_121F_10 ; mark it as such
  655. mov ax,LFLG_PHYSICAL
  656. i2f_121F_10:
  657. stosw ; set flags
  658. ; lea di,LDT_PDT
  659. lea si,ddsc_ptr-18h
  660. i2f_121F_20:
  661. lds si,18h[si]
  662. cmp si,-1
  663.  je i2f_121F_30
  664. cmp dl,[si] ; is this the DDSC for the drive
  665.  jne i2f_121F_20 ; if so save it away
  666. i2f_121F_30:
  667. xchg ax,si ; AX = DDSC offset
  668. stosw
  669. mov ax,ds ; AX = DDSC seg
  670. stosw
  671. ; lea di,LDT_BLK
  672. mov ax,0FFFFh ; AX = FFFF
  673. stosw ! stosw ! stosw ; fill in block info
  674. ; lea di,LDT_ROOTLEN
  675. mov ax,2
  676. stosw ; set root length
  677. pop di
  678. pop dx ! pop si ! pop ds
  679. ret
  680. i2f_1220:
  681. ; Get pointer to system file table number for handle BX into ES:DI
  682. push ds
  683. call get_dseg
  684. mov es,current_psp
  685. mov ax,6 ; assume illegal
  686. cmp bx,PSP_XFNMAX ; is it a legal handle
  687. cmc ; invert CY for error return
  688.  jc i2f_1220_10 ;  no, forget it
  689. les di,PSP_XFTPTR ; get XFT from PSP
  690. add di,bx ; add in the offset
  691. ; clc
  692. i2f_1220_10:
  693. pop ds
  694. ret
  695. i2f_1221:
  696. mov ah,MS_X_EXPAND ; let the FDOS do the walking...
  697. call DOS ;  and call our internal entry point
  698.  jnc i2f_1221_10
  699. neg ax ; get error code correct
  700. stc ;  before returning error
  701. i2f_1221_10:
  702. ret
  703. i2f_1222:
  704. ; Store error class, locus, action from DS:SI
  705. i2f_1222_10:
  706. lodsw
  707. cmp al,byte ptr error_code ; have we found the error ?
  708.  je i2f_1222_20
  709. inc al ; or hit the end of the list ?
  710.  jz i2f_1222_20
  711. lodsw ; skip this one
  712. jmp i2f_1222_10 ; and try the next
  713. i2f_1222_20:
  714. cmp ah,0ffh ; valid error class ?
  715.  je i2f_1222_30
  716. mov error_class,ah
  717. i2f_1222_30:
  718. lodsw
  719. cmp al,0ffh
  720.  je i2f_1222_40
  721. mov error_action,al
  722. i2f_1222_40:
  723. cmp ah,0ffh
  724.  je i2f_1222_50
  725. mov error_locus,ah
  726. i2f_1222_50:
  727. ret
  728. i2f_1223:
  729. ; On Entry buffer at 4E6 filled with Device name - eg. "NAME1   "
  730. ; Preserve word ptr [4E6]
  731. ; if byte ptr [4E6] = 5 then byte ptr [4E6] = E5
  732. ; if byte ptr [506] & 8 then exit now with STC
  733. ; otherwise work down device chain
  734. ; Find device driver for device NAME1
  735. ; Check if character device
  736. push ds
  737. call get_dseg
  738. if FALSE
  739. push word ptr name_buf ; save 1st char of name
  740. test magic_byte,8 ; magic location and number ??
  741.  jnz i2f_1223_40 ; can we do the check ?
  742. cmp name_buf,5
  743.  jne i2f_1223_10 ; if 1st char is 5, make it
  744. mov name_buf,0e5h ;  an E5
  745. i2f_1223_10:
  746. endif
  747. mov si,offset nul_device ; start from NUL
  748. i2f_1223_20:
  749. test ds:DH_ATTRIB[si],DA_CHARDEV
  750.  jz i2f_1223_30 ; skip unless character device
  751. mov cx,8
  752. lea di,name_buf ; point at name we are looking for
  753. push si
  754. lea si,ds:DH_NAME[si] ; point a device name
  755. repe cmpsb ; compare the names
  756. pop si
  757.  jne i2f_1223_30 ; if we found it, save info
  758. mov es:word ptr current_device,si
  759. mov es:word ptr current_device+2,ds
  760. mov bh,ds:byte ptr DH_ATTRIB[si]
  761. or bh,0e0h
  762. xor bh,20h ; clear this bit
  763. clc ; we found it
  764. jmps i2f_1223_50
  765. i2f_1223_30:
  766. lds si,ds:DH_NEXT[si]
  767. cmp si,0ffffh ; any more entries ?
  768.  jne i2f_1223_20 ; yes, do them
  769. i2f_1223_40:
  770. stc
  771. i2f_1223_50:
  772. if FALSE
  773. pushf
  774. call get_dseg ; we may have scambled DS
  775. popf
  776. pop word ptr name_buf ; restore 1st character
  777. endif
  778. pop ds
  779. ret
  780. i2f_1225:
  781. ; Get length of ASCIIZ string DS:SI
  782. call strlen
  783. inc cx ; include the terminating zero
  784. mov ax,8[bp] ; restore AX from stack
  785. ret
  786. ; The following are NOT required for MSNET - they are used by NLSFUNC
  787. i2f_1226:
  788. ; Open the file at DS:DX
  789. mov al,cl ; open mode in CL on entry
  790. mov ah,MS_X_OPEN ; open the file
  791. DOS:
  792. push ds ! push es ! pop ds ! pop es
  793. call dos_entry ; reverse DS/ES before for dos_entry
  794. push ds ! push es ! pop ds ! pop es
  795. ret
  796. i2f_1227:
  797. ; Close file BX
  798. mov ah,MS_X_CLOSE ; close the file
  799. jmps DOS
  800. i2f_1228:
  801. ; LSEEK on file BX
  802. mov ax,[bp] ; seek mode in BP on entry
  803. mov ah,MS_X_LSEEK ; do the seek
  804. jmps DOS
  805. i2f_1229:
  806. ; Read from file BX
  807. mov ah,MS_X_READ
  808. jmps DOS
  809. i2f_122A:
  810. ; Set fastopen entry point to DS:SI
  811. ; SI = FFFF, sdont't set - just check if installed
  812. mov ax,si ; AX = offset
  813. inc ax ; AX = 0 if it's an installation check
  814. stc ; assume it is, and say not installed
  815.  jne i2f_122A_10
  816. clc ; fail new installation
  817. i2f_122A_10:
  818. ret
  819. i2f_122B:
  820. ; IOCTL
  821. mov al,[bp] ; get IOCTL minor
  822. mov ah,MS_X_IOCTL
  823. jmps DOS
  824. i2f_122C:
  825. ; Get 2nd device driver header address
  826. push ds
  827. call get_dseg
  828. lds ax,ds:dword ptr nul_device
  829. mov bx,ds ; BX:AX -> 2nd device header
  830. pop ds
  831. ret
  832. i2f_122D:
  833. ; Get extended error code
  834. mov ax,error_code
  835. ret
  836. ;
  837. ; Our FDOS extentions live here
  838. ;
  839. if DELWATCH
  840. extrn locate_buffer:near
  841. extrn flush_drive:near
  842. extrn delfat:near
  843. extrn allocate_cluster:near
  844. extrn getblk:near
  845. extrn change_fat_entry:near
  846. extrn fixup_hashing:near
  847. ; for speed/code size we just call directly in BLACK.A86
  848. endif
  849. i2f_10tbl dw i2f_10nyi ; never gets here...
  850. dw i2f_1001 ; install fdos hook
  851. if DELWATCH
  852. if FALSE
  853. dw i2f_1002 ; read buffer
  854. dw i2f_1003 ; flush buffers
  855. dw i2f_1004 ; free fat chain
  856. dw i2f_1005 ; allocate cluster
  857. dw i2f_1006 ; next cluster
  858. dw i2f_1007 ; update fat entry
  859. dw i2f_1008 ; fixup checksums
  860. else
  861. dw locate_buffer ; ask BLACK to find that buffer
  862. dw flush_drive ; ask BLACK to flush buffers
  863. dw delfat ; ask BLACK to release FAT chain
  864. dw allocate_cluster; ask DEBLOCK to allocate space
  865. dw getblk ; ask DEBLOCK to return next block
  866. dw change_fat_entry; ask DEBLOCK to update fat entry
  867. dw fixup_hashing ; ask BLACK to fixup hashing/checksums
  868. endif
  869. dw i2f_1009 ; directory buffer info
  870. endif
  871. i2f_10size equ (offset $ - offset i2f_10tbl)/2
  872. i2f_1001:
  873. ;--------
  874. ; install fdos stub
  875. ;
  876. ; On Entry:
  877. ; DX:AX -> new fdos_stub entry address
  878. ; On Exit:
  879. ; None
  880. ;
  881. call get_dseg ; get PCMode data seg
  882. mov word ptr fdos_stub,ax ; fixup our share stubs
  883. mov word ptr fdos_stub+WORD,dx
  884. i2f_10nyi:
  885. ret
  886. if DELWATCH
  887. if FALSE
  888. i2f_1002:
  889. ;--------
  890. ; read buffer
  891. ; On Entry:
  892. ; CH = 0FFh (pre-read required)
  893. ; CL = BF_ISFAT/BF_ISDIR/BF_ISDATA
  894. ; AH:DX = 24 bit sector number
  895. ; On Exit:
  896. ; ES:SI -> Buffer control block
  897. ;
  898.     jmp locate_buffer       
  899. i2f_1003:
  900. ;--------
  901. ; flush buffers
  902. ; On Entry:
  903. ; AL = drive
  904. ; AH = buffer type to flush (BF_ISFAT+BF_ISDIR+BF_ISDATA)
  905. ; On Exit:
  906. ; None
  907. ;
  908.     jmp flush_drive     
  909. i2f_1004:
  910. ;--------
  911. ; free fat chain
  912. ; On Entry:
  913. ; AX = 1st block to release on current drive
  914. ; On Exit:
  915. ; None
  916.     jmp delfat          
  917. i2f_1005:
  918. ;--------
  919. ; allocate cluster
  920. ; On Entry:
  921. ; AX = block to start search from (eg. current end of file)
  922. ;      0000 = start of disk
  923. ; On Exit:
  924. ; AX = 0000 if none available
  925. ;      else allocated block (marked as End Of Chain)
  926. ;
  927. jmp allocate_cluster ; ask DEBLOCK.A86 to allocate some space
  928. i2f_1006:
  929. ;--------
  930. ; get next cluster
  931. ; On Entry:
  932. ; AX = current block
  933. ; On Exit:
  934. ; AX = next block in chain
  935. ;
  936. jmp getblk ; ask DEBLOCK.A86 to return next block
  937. i2f_1007:
  938. ;--------
  939. ; change fat entry
  940. ; On Entry:
  941. ; AX = fat entry to change
  942. ; DX = new value
  943. ; On Exit:
  944. ; None
  945. ;
  946. jmp change_fat_entry ; ask DEBLOCK.A86 to modify FAT entry
  947. i2f_1008:
  948. ;--------
  949. ; update hash code for directory entry on current drive
  950. ; On Entry:
  951. ; AX = segment of dir buffer
  952. ; CX = cluster to fixup (0 = root)
  953. ; DI = directory entry index(clipped to cluster if subdir)
  954. ; AX:SI-> dir entry (single entry for hashing)
  955. ; On Exit:
  956. ; None
  957. ;
  958. jmp fixup_hashing
  959. endif
  960. i2f_1009:
  961. ;--------
  962. ; return dirbuf info
  963. ; On Entry:
  964. ; None
  965. ; On Exit:
  966. ; ES:DI -> 128 byte directory record buffer
  967. ; ES:SI -> dir bcb structure
  968. ; 0[si] = drive (FF = invalid)
  969. ; 1[si] = low byte of record number
  970. ; 2[si] = mid byte of record number
  971. ; 3[si] =  hi byte of record number
  972. ;
  973. push cs ! pop es
  974. mov si,offset invalid_dir_bcb
  975. ret
  976. invalid_dir_bcb db 0ffh ; drive is invalid
  977. ; db ?,?,? ; don't bother about record number
  978. endif ;DELWATCH
  979. WindowsHooks:
  980. ;------------
  981. ; On Entry:
  982. ; AH = 16h, it's a windows broadcast
  983. ; AL = subfunction, other regs as appropriate
  984. ; On Exit:
  985. ; Various
  986. ;
  987. if DOS5
  988. cmp al,07h ; 1607: Virtual device init
  989.  je WindowsDOSMGR
  990. endif
  991. test dx,1 ; is it a DOSX broadcast ?
  992.  jnz WindowsExit
  993. cmp al,05h ; 1605: Windows enhanced mode init
  994.  je WindowsStartup
  995. if DOS5
  996. cmp al,06h ; 1606: Windows enhanced mode exit
  997.  je WindowsShutdown
  998. endif
  999. WindowsExit:
  1000. iret
  1001. WindowsStartup:
  1002. ;--------------
  1003. push ds
  1004. call get_dseg ; DS -> our data
  1005. if DOS5
  1006. inc criticalSectionEnable ; enable Int 2Ah for Windows
  1007. inc WindowsHandleCheck
  1008. endif
  1009. ;;if 0 Put this back in, as instance data still required
  1010. ;; Removed pointer to vxd in HEADER.A86   BAP
  1011. mov SwStartupInfo+2,bx ; Commented out, as NWDOS.386
  1012. mov SwStartupInfo+4,es ; no longer needed.
  1013. push ds
  1014. pop es ; ES -> pcmode data
  1015. mov bx,offset SwStartupInfo
  1016. ;;endif
  1017. jmp int2F_BIOS ; pass on to the BIOS
  1018. if DOS5
  1019. WindowsShutdown:
  1020. ;---------------
  1021. push ds
  1022. call get_dseg ; DS -> our data
  1023. dec criticalSectionEnable ; enable Int 2Ah for Windows
  1024. dec WindowsHandleCheck
  1025. pop ds
  1026. sub dx,dx ; return success
  1027. iret
  1028. WindowsDOSMGR:
  1029. ;-------------
  1030. cmp bx,15h ; is it DOS manager?
  1031.  jne WindowsExit ; forget the others
  1032. ; cmp cx,0
  1033.  jcxz WindowsCX0
  1034. dec cx
  1035.  jcxz WindowsCX1
  1036. dec cx ! dec cx ! dec cx
  1037.  jcxz WindowsCX4
  1038. dec cx
  1039.  jcxz WindowsCX5
  1040. iret
  1041. WindowsCX0:
  1042. ;----------
  1043. push ds
  1044. call get_dseg
  1045. push ds
  1046. pop es ; ES = DOS data segment
  1047. pop ds
  1048. lea bx,windowsData ; ES:BX -> secret variables
  1049. inc cx ; tell them we've responded
  1050. iret
  1051. WindowsCX1:
  1052. ;----------
  1053. mov bx,dx ; entry DX=1Fh, exit BX=1Fh
  1054. mov ax,0B97Ch ; AX, DX are magic values
  1055.     mov dx,0A2ABh       
  1056. ; xor cx,cx ; CX = 0
  1057. iret
  1058. WindowsCX4:
  1059. ;----------
  1060. xor dx,dx
  1061. ; xor cx,cx ; CX = 0
  1062. iret
  1063. WindowsCX5:
  1064. ;----------
  1065. ; entry: ES:DI -> device driver
  1066. ; determine device driver size in bytes
  1067. push ds
  1068. test di,di ; not primary DEVICE= driver?
  1069.  jnz WindowsCX5NoDev ; can't have DMD preceeding it
  1070. mov ax,es ; get device segment
  1071. dec ax ; DMD is one paragraph lower down
  1072. mov ds,ax ; DS:DI -> device DMD
  1073. inc ax ; AX = device driver segment
  1074. cmp ds:byte ptr 0[di],'D' ; see if 'D'device=
  1075.  jne WindowsCX5NoDev ; skip if not
  1076. cmp ax,ds:word ptr 1[di] ; owned by the driver ?
  1077.  jne WindowsCX5NoDev ; skip if not
  1078. mov ax,10h ; bytes per paragraph
  1079. mul ds:word ptr 3[di] ; bytes in device driver
  1080. pop ds
  1081. mov bx,dx ; BX = high word
  1082. xchg ax,cx ; CX = low word
  1083. mov ax,0B97Ch ; AX, DX are magic values
  1084.     mov dx,0A2ABh       
  1085. iret
  1086. WindowsCX5NoDev:
  1087. ; ES:DI -> not an external device 
  1088. pop ds
  1089. xor ax,ax
  1090. xor dx,dx
  1091. ; xor cx,cx ; CX = 0
  1092. iret
  1093. endif
  1094. eject
  1095. PCMODE_DATA DSEG WORD
  1096. extrn hmaRoot:word
  1097. extrn last_drv:byte
  1098. extrn phys_drv:byte
  1099. extrn ddsc_ptr:dword
  1100. extrn current_psp:word
  1101. extrn current_dsk:byte
  1102. extrn net_delay:word
  1103. extrn nul_device:byte
  1104. extrn error_code:word
  1105. extrn error_class:byte
  1106. extrn error_action:byte
  1107. extrn error_locus:byte
  1108. extrn file_ptr:dword
  1109. extrn ldt_ptr:dword
  1110. extrn current_device:dword
  1111. extrn current_ldt:dword
  1112. extrn current_dhndl:dword
  1113. extrn current_ddsc:dword
  1114. extrn yearsSince1980:byte
  1115. extrn days_in_month:byte
  1116. extrn name_buf:byte
  1117. extrn int21regs_ptr:dword
  1118. extrn int24_esbp:dword
  1119. extrn int2FNext:dword
  1120. extrn fdos_stub:dword
  1121. extrn SwStartupInfo:word
  1122. extrn err_drv:byte
  1123. extrn rwmode:byte
  1124. if DOS5
  1125. extrn indos_flag:byte, machine_id:byte, internal_data:byte, dmd_upper_root:word
  1126. extrn criticalSectionEnable:byte
  1127. extrn WindowsHandleCheck:byte
  1128. GLOBAL_DATA dseg
  1129. windowsData dw 5 ; version number ?
  1130. dw $ ; dummy
  1131. dw $ ; dummy
  1132. dw offset indos_flag
  1133. dw offset machine_id
  1134. dw offset internal_data-10
  1135. dw offset dmd_upper_root
  1136. else
  1137. extrn bcb_root:dword
  1138. endif
  1139. end