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

操作系统开发

开发平台:

Asm

  1. ;    File              : $PCMIF.A86$
  2. ;
  3. ;    Description       :
  4. ;
  5. ;    Original Author   : DIGITAL RESEARCH
  6. ;
  7. ;    Last Edited By    : $CALDERA$
  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. ;    PCMIF.A86 1.21 93/09/09 22:36:50
  33. ;    Int 21/59 uses error stack 
  34. ;    PCMIF.A86 1.20 93/08/27 18:56:30 
  35. ;    Int 25/26 32 bit sector detection
  36. ;    PCMIF.A86 1.19 93/07/22 19:30:54 
  37. ;    chnage int 25/26 support for NDD 
  38. ;    PCMIF.A86 1.18 93/07/20 22:47:54 
  39. ;    Even fewer checks on int 25/26 
  40. ;    PCMIF.A86 1.14 93/05/06 19:28:31
  41. ;    Move int 23/28 support to CIO.
  42. ;    PCMIF.A86 1.13 93/05/05 23:31:0
  43. ;    int 2A/84 is now only generated on input-and-wait functions
  44. ;    PCMIF.A86 1.12 93/03/25 15:06:48
  45. ;    tweak int21 entry
  46. ;    ENDLOG
  47. ;
  48. ; 24 Aug 87 The CARRY flag is now preserved for all DOS functions below
  49. ;           038h Get/Set Country Code.
  50. ; 04 Sep 87 Display the Interrupt Number and Registers when an illegal
  51. ;           software interrupt is executed by an application. This
  52. ;           is disabled by DBG OFF.
  53. ; 09 Sep 87 DDIO interface changed to support a Double Word sector
  54. ;           number.
  55. ; 05 Oct 87 Critical Error abort routine now uses the correct 
  56. ;           terminate code.
  57. ; 14 Oct 87 INT2F responds like a Network Redirector
  58. ; 28 Oct 87 Preserve the state of the INDOS_INTERNAL flag during multiple
  59. ;           calls through DOS_ENTRY
  60. ; 29 Oct 87 DS now points at the IBM PC ROS during an INT1B and INT1B
  61. ;           moved into IBMROS.
  62. ;  7 Nov 87 Removal of development flags
  63. ;  5 Jan 88 Terminate CP/M applications making DOS Calls in Concurrent DOS
  64. ; 26 Feb 88 Terminate DOS applications making CP/M calls in DOSPLUS
  65. ; 26 Apr 88 INT25/26 error codes only translated for Concurrent
  66. ; 18 May 88 Prevent corruption of the EXIT_CODE by INT23 and INT24
  67. ;           when the application does not return.
  68. ; 23 May 88 Prevent termination during CONFIG.SYS processing in DOSPLUS
  69. ; 26 May 88 Force INDOS and ERROR flags to ZERO on terminate
  70. ;  1 Jun 88 Modify INT28 to execute delays and work with SideKick.
  71. ; 15 Jul 88 Support the IDLECNT field in the Process Descriptor and
  72. ;           CCB BUSY bit.
  73. ; 07 Sep 88 PolyTron PolyWindows make DOS functions calls whenever
  74. ;           CS < SS. Therefore during the INT21 Entry and Exit code
  75. ;           interrupts must be disabled untill the stack swap occurs
  76. ;           even though the INDOS_FLAG is non-zero.
  77. ; 24 Oct 88 File Lock/Unlock is now treated as an INACTIVE function.
  78. ;  4 Nov 88 Correct the INT25/26 Error Translation Code
  79. ; 21 Nov 88 Make INt25/26 Error Translation even better.
  80. ; 29 Nov 88 Command Line Editor Insert on by default.
  81. ; 21 Dec 88 IJs IDLE detection improvement only DELAY if someone else is
  82. ;           ready to run.
  83. ; 11 Jan 89 Inc/Dec INTERNAL_FLAG to support DOS_ENTRY reentrancy.
  84. ; 30 Jan 89 Inc/Dec INDOS_FLAG to INT25/26 Direct Disk I/O (CHKDSK/PRINT)
  85. ; 19 Feb 89 Check the SHARE_FLAG for SHARING status in DR DOS
  86. ;  9 Mar 89 Save/Restore PSP_USERSP/SS round int28's (SKPLUS/LINK/CTRL-C)
  87. ; 18 Apr 89 ij Maintain the INDOS_FLAG correctly while processing INT 24
  88. ; 18 Apr 89 Only take over INTs 5B and 5C for Debug Systems
  89. ; 22 May 89 Setup DS before testing the state of the Share Flag.
  90. ; 25 May 89 Support INT28_FLAG for functions 01 to 0C inclusive
  91. ; 31 May 89 Move break_sp into DOS internal data area
  92. ;  1 Jun 89 Save PSP_USERSS and SP during a critival Error (INT 24)
  93. ; 05 Jun 89 Return NOT present for ASSIGN command and TRUE state for APPEND
  94. ; 29 Jun 89 Save/restore retry_sp & retry_off around INT 24
  95. ; 10 Jul 89 INT27 corrected to handle memory size of XXX1 (INFORM)
  96. ; 31 Jul 89 Move stacks to DATA.PCM (CDROM support under way...)
  97. ; 11 Aug 89 Create INT2F.PCM to support real INT 2F functions
  98. ;  6 Sep 89 INT2A/84 keyboard busy loop added to do_int28
  99. ; 23 Oct 89 MON_PERM removed from func5D/func5E/func5F (pain with MSNET..)
  100. ;  9 Nov 89 Int 5B & 5C no longer taken over in DRDOS Debug versions
  101. ;           (Conflicts with PC-Net)
  102. ; 15 Jan 90 pcmode_swapin/pcmode_swapout added for paged isr support
  103. ; 25/Jan/90 Support Idle Data Area
  104. ; 25/Jan/90 Add forth stack to support Japanese FEP and PTHOT.
  105. ; 29/Jan/90 keep int21 CS/IP/FLAGS on local stack
  106. ; 13/Feb/90 Added func63.
  107. ; 20/Feb/90 CDOS checks caller is DOS process and aborts if not.
  108. ; 22/Feb/90 Int25/26 checks disk label for passwords
  109. ;           Also swaps to normal stack like others DOS's
  110. ;  7 Mar 90 Convert to register preserved function calls
  111. ; 16 Mar 90 Int25/26 checks out for Leopard Beta 2
  112. ;  4 Jun 90 Int21/25&35 don't swap stacks-ANSI.SYS Framework DOS window bug
  113. ;  7 Jun 90 Print Rite fix moves to init.pcm
  114. ; 29 Jun 90 CDOS idle detection uses timer info
  115. ;  9 Aug 90 Int 8 tick count packed in P_CMOD
  116. ; 19 Sep 90 load current_psp before checking PSP_PIDF (thanks Datapac)
  117. ;  4 Oct 90 improved control break handling
  118. ; 11 Oct 90 dev_map now supported to set LPTn/COMn mapping
  119. ;  1 Nov 90 default Int 24 handler returns "Fail"
  120. ; 19 feb 91 do_int28 calls read_time_and_date (BIOS CLOCK needs a call
  121. ;           every day)
  122. ; 14 jun 91 copy user regs to local copy after int24 for pcshell
  123. ;  8 aug 91 SI preserved on Int25/26 for SCAN 7.7
  124. include pcmode.equ
  125. include fdos.def
  126. include vectors.def
  127. include i:msdos.equ
  128. include i:mserror.equ
  129. include i:psp.def
  130. include i:fdos.equ
  131. PCM_CODE CSEG BYTE
  132. extrn pcmode_dseg:word
  133. extrn break_check:near ; Control-C Check 
  134. extrn error_exit:near
  135. extrn fdos_nocrit:near
  136. extrn get_ddsc:near
  137. eject
  138. ;
  139. ; This entry point is used when a CALLF PSP:0005 has been executed
  140. ; Here the function number is passed in CL and not AH and only
  141. ; functions 0 to 24 inclusive can be executed.
  142. ;
  143. ; Entry Stack -> INT 21 Stack
  144. ;
  145. ; SP + 04 Return Offset Current Flags
  146. ; SP + 02  PSP Segment  PSP Segment
  147. ; SP + 00    000Ah Return Offset
  148. ;
  149. Public call5_entry
  150. call5_entry:
  151. pop ax ; Remove 000Ah return Offset
  152. pushf ; Save the Flags
  153. push bp ! mov bp,sp ; Get Stack Frame Pointer
  154. mov ax,02[bp] ; Get the FLAGS
  155. xchg ax,06[bp] ; Swap with the return offset
  156. mov 02[bp],ax ; and then save the return offset
  157. pop bp ; Restore the BP register
  158. mov ah,cl ; Make it look like an INT 21
  159. cmp ah,024h ; Check for a valid function for this
  160. jbe int21_entry ; entry technique if not return
  161. illegal_iret:
  162. mov al,0
  163. iret
  164. int21_e01:
  165. mov ds,word ptr .INT31_SEGMENT
  166. jmps int21_e02
  167. eject
  168. ; ++++++++++++++++++++++++++
  169. ; Int 20 - Program Terminate
  170. ; ++++++++++++++++++++++++++
  171. ;
  172. Public int20_entry
  173. int20_entry:
  174.     mov ah,00h          
  175. ; jmps int21_entry ; and jump to the standard entry point
  176. eject
  177. ; +++++++++++++++++++++++++
  178. ; Int 21 - Function Request
  179. ; +++++++++++++++++++++++++
  180. ;
  181. Public int21_entry
  182. int21_entry:
  183. cmp ah,pcmode_ftl ; is it in range ?
  184.  ja illegal_iret ;  no, return BEFORE enabling ints
  185. cld ; Clear the direction flag
  186. PUSH$DOS ; Save User Registers
  187. mov ds,pcmode_dseg ; get CS relative Data Segment
  188. test pcmode_dseg,0FFFFh ; if Data Segment is zero then get
  189.  jz int21_e01 ; the Data segment address from
  190. int21_e02: ; the segment portion of INT 31
  191. ;
  192. ; The following routines execute on the users stack without
  193. ; modifing the INDOS_FLAG etc. These routines should only read
  194. ; or update BASIC system variables.
  195. ;
  196. cmp ah,33h ; Func 33h - Control Break
  197.  je int21_e10
  198. cmp ah,50h ; Func 50h - Set PSP
  199.  jb int21_e20
  200. cmp ah,51h ; Func 51h - Get PSP
  201.  jbe int21_e10
  202. cmp ah,62h ; Func 62h - Get PSP
  203.  jne int21_e20
  204. int21_e10:
  205. mov bp,sp ; Calculate the Stack Frame address
  206. call internal_func ; "jump" to appropriate routine
  207. jmp int21_exit
  208. int21_e20:
  209. inc indos_flag ; Increment the INDOS Flag
  210. mov int21AX,ax ; save function number
  211. if DOS5
  212. cmp WindowsHandleCheck,26h ; is windows active ?
  213.  jne int21_e30
  214. mov ax,LocalMachineID ; get local machine ID (zero unless
  215. mov machine_id,ax ;  we are multi-tasking)
  216. else
  217.     callf   win386_local_machine    
  218. cmp machine_id,0 ; did it nobble the machine ID
  219.  jnz int21_e30 ; if so leave it alone
  220. mov ax,LocalMachineID ; get local machine ID (zero unless
  221. mov machine_id,ax ;  we are multi-tasking)
  222. endif
  223. int21_e30:
  224. mov ax,current_psp
  225. mov owning_psp,ax
  226. mov es,ax ; Get the PSP
  227. mov ax,sp
  228. mov PSP_USERSP,ax ; Save the SS:SP pointer to 
  229. mov PSP_USERSS,ss ; the register image ready for any
  230. ; Critical errors that might occur
  231. xchg ax,int21regs_off ; point to callers registers
  232. mov prev_int21regs_off,ax ; while saving current
  233. mov ax,ss ;  pointer to cater for
  234. xchg ax,int21regs_seg ;  re-entrancy
  235. mov prev_int21regs_seg,ax
  236. xor ax,ax
  237. mov remote_call,ax ; indicate we are a local call
  238. mov int28_flag,al ; Do NOT Generate INT 28s
  239. mov ax,ds
  240. mov ss,ax ; swap initially to the error
  241. mov sp,offset error_stack ;  stack until we know better
  242. mov ax,int21AX ; reload AX
  243. sti
  244. cmp ah,59h ; Func 59h - Return Extended Error
  245.  je int21_e50 ;  use the error stack
  246. cmp ah,0Ch ; are we a character function
  247.  ja int21_e40 ;  in range 01-0C ?
  248. cmp ah,00h
  249.  je int21_e40
  250. cmp error_flag,0 ; Use the "ERROR" Stack for the above
  251.  jnz int21_e50 ;  functions 01-0C if error_flag set
  252. mov sp,offset indos_stack ; else use the "INDOS" stack for these
  253. mov int28_flag,TRUE ;  functions and generate INT 28s
  254. jmps int21_e50
  255. int21_e40:
  256. mov error_flag,0 ; clear the error flag in case someone
  257. ; hasn't returned from an Int 24
  258. push ax ; save function on stack
  259. mov ah,82h ; magic number in AH
  260. int 2ah ; call server hook
  261. pop ax ; recover function number
  262. mov sp,offset normal_stack ; switch to the NORMAL stack
  263. test break_flag,0FFh ; is the Break Flag ON
  264.  jz int21_e50 ;  NO - So continue
  265. call break_check ; Handle the Control-C
  266. int21_e50:
  267. if IDLE_DETECT
  268. test idle_flags,IDLE_DISABLE ; don't break the pipeline unless
  269.  jz int21_idle ;  IDLE checking enabled
  270. int21_e60:
  271. endif
  272. call int21_func ; Execute the function
  273. cli ; Stop anybody interfering
  274. les bp,int21regs_ptr ; point to user stack
  275. mov es:reg_AL[bp],al ; always return AL
  276. mov ax,prev_int21regs_off
  277. mov int21regs_off,ax
  278. mov ax,prev_int21regs_seg
  279. mov int21regs_seg,ax
  280. mov ax,es
  281. mov ss,ax ; back to users stack
  282. mov sp,bp
  283. dec indos_flag ; Decrement the INDOS_FLAG
  284. ; jmp int21_exit
  285. Public int21_exit
  286. int21_exit:
  287. POP$DOS ; Restore Registers
  288. iret
  289. eject
  290. if IDLE_DETECT
  291. ; Only called if Idle detection is enabled
  292. ; AH,DL as on Int 21 Entry
  293. ; Decide if function is active/inactive
  294. int21_idle:
  295. ;----------
  296. if IDLE_DETECT
  297. mov bx,int28_reload ; reset the INT28 delay counter
  298. mov int28_delay,bx ;  with the Reload value
  299. endif
  300. cmp ah,5Ch ! je int21_inactive ; Treat Lock/Unlock as inactive some
  301. ; applications poll locked record.
  302. cmp ah,44h ! je int21_inactive ; IO Control Treated as Inactive
  303. cmp ah,2Ch ! ja int21_active ; > Get Current Time all active
  304.      je int21_inactive ; Get Current Time inactive
  305. cmp ah,2Ah ! je int21_inactive ; Get Current Date inactive
  306. cmp ah,0Bh ! je int21_inactive ; Console Status
  307. cmp ah,0Ch ! je int21_inactive ; Flush and Invoke Treated as Inactive
  308. cmp ah,19h ! je int21_inactive ; Get Current Disk
  309. cmp ah,06h ! jne int21_active ; Treat RAW_IO Status as Inactive
  310. cmp dl,0FFh ! je int21_inactive ;
  311. int21_active: ; Active function Executed
  312. or idle_flags,IDLE_DOSFUNC ; set DOSFUNC flag for BIOS
  313. call active ; remember we were active
  314. jmps int21_e60 ; continue execution
  315. int21_inactive:
  316. call inactive ; Process this INACTIVE function
  317. jmps int21_e60
  318. Public inactive
  319. inactive:
  320. push es ! push ax
  321. dec active_cnt ; Decrement the count
  322. jnz inactive_10 ; Return if Non-Zero
  323. mov ax,idle_max ; Get the default count value
  324. mov active_cnt,ax ; and reset the internal count
  325. test idle_flags,IDLE_DISABLE ; Has Idle Checking been enabled
  326.  jnz inactive_10 ; Skip if NO.
  327. mov ax,PROC_IDLE ; Process is IDLE
  328. callf idle_vec ; Call the IDLE Handler
  329. inactive_10:
  330. pop ax ! pop es
  331. ret
  332. ;
  333. ; This routine will reset the active count for functions which
  334. ; are treated as INACTIVE but which have active sub-functions.
  335. ;
  336. Public active
  337. active:
  338. push ax
  339. mov ax,idle_max ; Get the default count value
  340. mov active_cnt,ax ; and reset the internal count
  341. pop ax
  342. ret
  343. endif
  344. ;
  345. ;
  346. ; This function is invoked for functions number above the last 
  347. ; supported function number. It forces AL to zero and returns.
  348. ; Just that and nothing more.
  349. ms_zero_AL:
  350. xor ax,ax ; AL = 0 for return
  351. ret
  352. eject
  353. ; DOS_ENTRY is used to call DOS functions internally.
  354. ; eg. Func4B (exec) calls MS_X_OPEN, MS_X_READ, MS_X_CLOSE etc.
  355. ; It is the responsibilty of the caller to make sure that no side
  356. ; effects exist if this entry point is used.
  357. ; eg. critical error handling
  358. ;
  359. ;
  360. Public dos_entry
  361. dos_entry:
  362. clc
  363. cld
  364. pushf ; look like Int21 registers
  365. pushf ! pushf ; fake CS/IP positions
  366. push ds ! push es ; Save registers on the USER stack
  367. push bp ; no Stack Swap is executed and DS
  368. push di ! push si ; and ES are swapped.
  369. push dx ! push cx
  370. push bx ! push ax
  371. mov bp,sp ; Initialise Stack Frame
  372. call get_dseg ; Get our Data Area
  373. inc internal_flag
  374. push fdos_data+0*WORD ; save fdos pblk so we can
  375. push fdos_data+1*WORD ;  be re-entrant(ish)
  376. push fdos_data+2*WORD
  377. push fdos_data+3*WORD
  378. push fdos_data+4*WORD
  379. push fdos_data+5*WORD
  380. push fdos_data+6*WORD
  381. push int21regs_off
  382. push int21regs_seg
  383. mov int21regs_off,bp
  384. mov int21regs_seg,ss
  385. call internal_func ; Execute the function
  386. mov reg_AL[bp],al ; always return AL to caller
  387. pop int21regs_seg
  388. pop int21regs_off ; restore previous pointer user REGS
  389. pop fdos_data+6*WORD
  390. pop fdos_data+5*WORD
  391. pop fdos_data+4*WORD
  392. pop fdos_data+3*WORD
  393. pop fdos_data+2*WORD
  394. pop fdos_data+1*WORD
  395. pop fdos_data+0*WORD ; restore fdos_pb for nested calls
  396. dec internal_flag
  397. pop ax ! pop bx ; Update the registers then
  398. pop cx ! pop dx ; set the flags and return
  399. pop si ! pop di ; to the user
  400. pop bp
  401. pop es ! pop ds
  402. popf ; discard dos_IP
  403. popf ;  and dos_CS
  404. popf ; get result
  405.  jnc dos_entry10
  406. neg ax ; return using our negative error
  407. stc ; conventions
  408. dos_entry10:
  409. ret
  410. Public int21_func
  411. int21_func:
  412. ;----------
  413. ; On Entry:
  414. ; AX, CX, DX, SI, DI as per Int 21
  415. ; BX = ??
  416. ; BP = ??
  417. ; DS = pcmode data
  418. ; ES = ??
  419. ; On Exit:
  420. ; (to client function)
  421. ; All general purpose registers as per Int 21 entry
  422. ; ES = dos_DS
  423. ;
  424. xor bx,bx ; BH = 0
  425. mov bl,ah ; BX = function number
  426. shl bx,1 ; make it a word offset
  427. push pcmode_ft[bx] ; save address of Function
  428. les bp,int21regs_ptr
  429. mov bx,es:reg_BX[bp] ; reload from dos_BX,dos_BP,and dos_DS
  430. les bp,es:dword ptr reg_BP[bp]
  431. ret
  432. internal_func:
  433. ;-------------
  434. ; On Entry:
  435. ; All registers as per Int 21 EXCEPT
  436. ; DS = pcmode data
  437. ; BP = dos_REGS stack frame
  438. ; On Exit:
  439. ; (to client function)
  440. ; ES = dos_DS
  441. ;
  442. mov al,ah ; function number in AL
  443. cbw ; AH = 0
  444. xchg ax,bx ; get subfunction in BX
  445. shl bx,1 ; make offset in the internal table
  446. push pcmode_ft[bx] ; save address of Function
  447. xchg ax,bx ; restore BX
  448. mov ax,reg_AX[bp] ; recover function number
  449. mov es,reg_DS[bp] ; ES = callers DS
  450. ret ; "jump" to handler
  451. eject
  452. ; INT25 and INT26 direct disk I/O interface
  453. ;
  454. ;Standard DOS 1.xx - 3.30 INT25/26 Interface
  455. ;===========================================
  456. ;
  457. ; entry: al = drive number
  458. ; ds = DMA segment
  459. ; bx = DMA offset
  460. ; cx = number of sectors
  461. ; dx = beginning relative sector
  462. ;
  463. ;
  464. ;Enhanced DOS 3.31 INT25/26 Interface
  465. ;====================================
  466. ;
  467. ; If CX == 0FFFFh then the application is using the enhanced
  468. ; INT25/INT26 interface which allows access to more than 64K
  469. ; sectors.
  470. ;
  471. ; entry: al = drive number
  472. ; bx = Parameter block Offset
  473. ; ds = Parameter block Segment
  474. ;
  475. ; Parameter Block Format
  476. ;DS:BX -> DD Starting Sector No.
  477. ; DW Number of Sectors
  478. ; DD Transfer Address
  479. ;
  480. ;
  481. ; exit: C flag = 0 if successful
  482. ;        = 1 if unsuccessful
  483. ; ax = error code(if CF = 1)
  484. ;   ah physical error
  485. ;   al logical error
  486. ; Users orginal flags left on stack
  487. ;
  488. ;
  489. eject
  490. DDIO_INT13 equ     0
  491. DDIO_READ_OP equ     1
  492. DDIO_WRITE_OP equ     2
  493. ; ++++++++++++++++++++++++++++
  494. ; Int 26 - Absolute Disk Write
  495. ; ++++++++++++++++++++++++++++
  496. ;
  497. Public int26_entry
  498. int26_entry:
  499. mov  ah,DDIO_WRITE_OP ; This is a WRITE operation
  500. jmps int26_10
  501. ; +++++++++++++++++++++++++++
  502. ; Int 25 - Absolute Disk Read
  503. ; +++++++++++++++++++++++++++
  504. ;
  505. Public int25_entry
  506. int25_entry:
  507. mov  ah,DDIO_READ_OP ; This is a READ operation
  508. int26_10: ; Common Direct Disk I/O code
  509. cld
  510. push ds ! push es
  511. push dx ; save DX for FLASHCARD
  512. push ds ! pop es ; ES = callers DS
  513. call get_dseg ; Get PCMODE Data Segment
  514. inc indos_flag ; Update the INDOS_FLAG
  515. mov normal_stack+2,ss ; save users SS:SP
  516. mov normal_stack,sp
  517. cli
  518. push ds ! pop ss ; use normal stack when in here
  519. mov sp,offset normal_stack
  520. sti
  521. inc cx ; CX = FFFF indicates this is
  522.      jz int26_30       
  523. ; CHECK FOR PARITIONS > 32 MBytes...
  524. dec cx ; CX restored
  525. push es
  526. push ax
  527. push bx
  528. push dx
  529. call get_ddsc ; ES:BX -> DDSC_
  530. mov di,0201h ; assume bad drive
  531.  jc int26_20
  532. mov di,0207h ; assume large media, and this error
  533. if 0
  534. ; This code works out the total number of sectors on a drive
  535. mov ax,es:DDSC_NCLSTRS[bx] ; get last cluster #
  536. dec ax ;  make it # data clusters
  537. xor dx,dx
  538. mov dl,es:DDSC_CLMSK[bx] ; get sec/cluster -1
  539. inc dx ; DX = sec/cluster
  540. mul dx ; DX:AX = # data sectors
  541. add ax,es:DDSC_DATADDR[bx] ; add in address of 1st data sector
  542. adc dx,0
  543. else
  544. mov ax,es:DDSC_NCLSTRS[bx] ; get last cluster #
  545. xor dx,dx
  546. mov dl,es:DDSC_CLMSK[bx] ; get sec/cluster -1
  547. inc dx ; DX = sec/cluster
  548. mul dx ; DX:AX is vaguely the # sectors
  549. test dx,dx ; close enough for bill
  550. endif
  551. stc ; assume an error
  552.  jnz int26_20
  553. xor di,di ; DI = zero, no error
  554. int26_20:
  555. pop dx
  556. pop bx
  557. pop ax
  558. pop es
  559.  jnc int26_40
  560. xchg ax,di ; AX = error code
  561. jmps int26_60 ; return it
  562. int26_30:
  563. mov dx,es:word ptr 0[bx] ; Get Starting Sector Low
  564. mov di,es:word ptr 2[bx] ; Get Starting Sector High
  565. mov cx,es:word ptr 4[bx] ; Get No. of sectors to transfer
  566. les bx,es:dword ptr 6[bx] ; Tranfer Address Offset
  567. int26_40:
  568. mov FD_DDIO_DRV_OP,ax ; save drive and operation
  569. mov FD_DDIO_NSECTORS,cx ; No. of Sectors
  570. mov FD_DDIO_STARTLOW,dx ; Starting Sector No.
  571. mov FD_DDIO_STARTHIGH,di ; High Word of Sector Number
  572. mov  FD_DDIO_DMAOFF,bx ; DMA Offset
  573. mov FD_DDIO_DMASEG,es ; DMA Segment
  574. mov FD_FUNC,FD_DDIO
  575. call fdos_nocrit ; let the FDOS do the work
  576. neg ax ; AX is DOS extended error
  577.  jz int26_exit
  578. sub al,-ED_PROTECT ; get AL to Int24 error format
  579. cmp al,-(ED_GENFAIL-ED_PROTECT)
  580.      jbe    int26_50       
  581. mov al,-(ED_GENFAIL-ED_PROTECT)
  582. int26_50: ; no, make it general failure
  583. mov ah,al ; save error in AH
  584. mov bx,offset int13_error
  585. xlat int13_error ; convert error to int13 format
  586. xchg al,ah ; get errors in correct registers
  587. int26_60:
  588. stc ; Set the Carry Flag when an error
  589. int26_exit: ; Occurs and return to the calling app.
  590. cli
  591. mov ss,normal_stack+2 ; back to user stack
  592. mov sp,normal_stack
  593. sti
  594. dec indos_flag ; Update the INDOS_FLAG
  595. sti
  596. pop dx
  597. pop es ! pop ds ; restore callers registers
  598. retf ; leave flags on stack
  599. int13_error db 03h,02h,80h,01h,10h,02h,40h,02h,04h,02h,02h,02h,02h
  600. eject
  601. ; ++++++++++++++++++++++++++++++++++++
  602. ; Int 27 - Terminate but Stay Resident
  603. ; ++++++++++++++++++++++++++++++++++++
  604. ;
  605. Public int27_entry
  606. int27_entry:
  607. mov ax,3100h ; Convert this to a DOS 'Terminate and 
  608. add dx,15 ; Stay Resident' function by converting the
  609. rcr dx,1 ; memory size in bytes to paragraphs.
  610. shr dx,1 ; On entry DX == memsize + 1 bytes therefore
  611. shr dx,1 ; round upto a paragraph boundary by adding
  612. shr dx,1 ; 15 then divide by 16
  613. jmp int21_entry
  614. eject
  615. ;
  616. ; DO_INT24:
  617. ;     On Entry:-
  618. ; AH Set for INT 24
  619. ; AL Drive Number (0 = A:)
  620. ; DI Error Code
  621. ; ES:SI Device Header Control Block
  622. ;
  623. ;     On Exit:-
  624. ; AL Error Response Retry/Ignore/Fail
  625. ;
  626. ; INT 24 Critical Error:-
  627. ; On Entry:- AH/7 0 = Disk Device
  628. ; AH/5 0 = IGNORE is an Invalid Response
  629. ; AH/4 0 = RETRY in an Invalid Response
  630. ; AH/3 0 = FAIL is an Invalid Response
  631. ; AH/2-1 00= DOS Area
  632. ; 01= File Allocation Table
  633. ; 10= Directory
  634. ; 11= Data
  635. ; AH/0 0 = Read, 1 = Write
  636. ;
  637. ; AL 1 Retry the Operation
  638. ; BP:SI Device Header Control Block
  639. ; DI High Byte Undefined, Low Byte Error Code 
  640. ;
  641. ;     On Exit:- AL 0 = IGNORE Error
  642. ; 1 = RETRY the Operation
  643. ; 2 = TERMINATE using INT 23
  644. ; 3 = FAIL the current DOS function
  645. ;
  646. Public do_int24
  647. do_int24:
  648. cmp error_flag,0 ; Skip the critical error routine
  649. jz di24_05 ; if the handler is active
  650. mov al,ERR_FAIL ; Then return the FAIL condition
  651. ret ; to the calling routine
  652. di24_05:
  653. push ax ! push bp ; Save our Base Pointer and then the
  654. cli ; Disable Interupts
  655. mov bp,es ; BP:SI points to dev header
  656. mov es,current_psp ; Get the current PSP and USER Stack
  657. push PSP_USERSS ; Save the Users Real SS and SP
  658. push PSP_USERSP ; on the internal Stack
  659. push retry_sp ; also the retry info
  660. push retry_off
  661. push remote_call
  662. push machine_id
  663. mov critical_sp,sp ; Internal Stack Pointer Offset
  664. inc error_flag ; Entering Critical Error Handler
  665. dec indos_flag ; I may be gone some time....
  666. ; (an application error handler need
  667. ; never return so tidy up first)
  668. mov ss,PSP_USERSS ; Switch to the Users Stack
  669. mov sp,PSP_USERSP
  670. int 24h ; Call the Critical Error Handler
  671. cld
  672. cli ; paranioa.....
  673. call get_dseg ; Reload DS just in case someone at
  674. ; A-T or Lotus cannot read
  675. push ds ! pop ss ; Swap back to the Internal stack
  676. mov sp,critical_sp ; and process the returned info.
  677. pop machine_id
  678. pop remote_call
  679. pop retry_off ; restore retry info
  680. pop retry_sp
  681. mov es,current_psp ; Restore the Users original SS and
  682. pop PSP_USERSP ; SP registers from the Stack
  683. pop PSP_USERSS
  684. pop bp ! pop bx ; Restore BP and original AX
  685. sti
  686. mov error_flag,0
  687.     inc indos_flag  
  688. cmp al,ERR_IGNORE ! jnz di24_10 ; Check for IGNORE and force
  689. test bh,OK_IGNORE ! jnz di24_10 ; to become a FAIL if its an 
  690. mov al,ERR_FAIL ; invalid response.
  691. di24_10:
  692. cmp al,ERR_RETRY ! jnz di24_20 ; Check for RETRY and force
  693. test bh,OK_RETRY ! jnz di24_20 ; to become a FAIL if its an
  694. mov al,ERR_FAIL ; invalid response.
  695. di24_20:
  696. cmp al,ERR_FAIL ! jnz di24_30 ; Check for FAIL and force
  697. test bh,OK_FAIL ! jnz di24_30 ; to become a ABORT if its an
  698. mov al,ERR_ABORT ; invalid response.
  699. di24_30:
  700. cmp al,ERR_ABORT ; Do not return if the ABORT option
  701. jz di24_abort ; has been selected but execute
  702. ; INT 23 directly
  703. cmp al,ERR_FAIL ; All invalid reponses are converted
  704. ja di24_abort ; to ABORT
  705. di24_40:
  706. ret
  707. di24_abort: ; Abort this Process
  708. mov ax,current_psp ; check not root application because
  709. mov es,ax ; it must not be terminated so force
  710. cmp ax,PSP_PARENT ; Is this the root Process
  711. mov al,ERR_FAIL ; convert the error to FAIL
  712.  je di24_40 ; if not we terminate
  713. mov exit_type,TERM_ERROR ; Set the correct exit Type
  714. mov ax,04C00h ; and return code.
  715. mov int21AX,ax
  716. jmp func4C ; Then terminate
  717. eject
  718. ;
  719. ; Get the PCMODE Emulator data Segment from the PD
  720. ;
  721. Public get_dseg
  722. get_dseg:
  723. mov ds,pcmode_dseg ; get CS relative Data Segment
  724. test pcmode_dseg,0FFFFh ; If Data Segment is zero then get
  725. jz get_d10 ; the Data segment address from
  726. ret ; the segment portion of INT 31
  727. get_d10:
  728. mov ds,word ptr .INT31_SEGMENT
  729. ret
  730. ;
  731. ;INVALID_FUNCTION is called when any unsupported function has been executed
  732. ;
  733. Public invalid_function
  734. invalid_function:
  735. mov ax,ED_FUNCTION ; Mark as Invalid Function
  736. jmp error_exit ; and Exit
  737. eject
  738. Public reload_registers
  739. reload_registers:
  740. ;----------------
  741. ; This routine is called to reload the registers we expect to have correct
  742. ; at the start of a PCMODE function.
  743. push ds
  744. lds bp,int21regs_ptr
  745. mov ax,ds:reg_AX[bp]
  746. mov bx,ds:reg_BX[bp]
  747. mov cx,ds:reg_CX[bp]
  748. mov dx,ds:reg_DX[bp]
  749. mov si,ds:reg_SI[bp]
  750. mov di,ds:reg_DI[bp]
  751. les bp,ds:dword ptr reg_BP[bp]
  752. pop ds
  753. ret
  754. PCMODE_DATA DSEG WORD
  755. extrn retry_sp:word
  756. extrn retry_off:word
  757. extrn break_flag:byte
  758. extrn current_psp:word
  759. extrn current_dsk:byte
  760. extrn dma_offset:word
  761. extrn dma_segment:word
  762. extrn error_flag:byte
  763. extrn error_stack:word
  764. extrn exit_type:byte
  765. extrn int21regs_ptr:dword
  766. extrn int21regs_off:word
  767. extrn int21regs_seg:word
  768. extrn prev_int21regs_ptr:dword
  769. extrn prev_int21regs_off:word
  770. extrn prev_int21regs_seg:word
  771. extrn indos_flag:byte
  772. extrn indos_stack:word
  773. extrn LocalMachineID:word
  774. extrn machine_id:word
  775. extrn int21AX:word
  776. extrn normal_stack:word
  777. extrn owning_psp:word
  778. extrn remote_call:word
  779. if DOS5
  780. extrn WindowsHandleCheck:byte
  781. else
  782. extrn win386_local_machine:dword
  783. endif
  784. if IDLE_DETECT
  785. extrn active_cnt:word
  786. extrn idle_max:word
  787. extrn idle_flags:word
  788. extrn idle_vec:dword
  789. extrn int28_delay:word
  790. extrn int28_reload:word
  791. endif
  792. extrn critical_sp:word
  793. extrn internal_flag:byte
  794. extrn int28_flag:byte
  795. PCM_CODE CSEG BYTE
  796. ;
  797. ; The following Function tables are forced onto a word boundary
  798. ; because of the word alignment of the PCMODE_RODATE segment.
  799. ; Only word based Read Only data is held in this segment.
  800. ;
  801. extrn func00:near, func01:near, func02:near, func03:near
  802. extrn func04:near, func05:near, func06:near, func07:near
  803. extrn func08:near, func09:near, func0A:near, func0B:near
  804. extrn func0C:near, func0D:near, func0E:near, func0F:near
  805. extrn func10:near, func11:near, func12:near, func13:near
  806. extrn func14:near, func15:near, func16:near, func17:near
  807. extrn func19:near, func1A:near, func1B:near, func1C:near
  808. extrn func1F:near, func21:near, func22:near, func23:near
  809. extrn func24:near, func25:near, func26:near, func27:near
  810. extrn func28:near, func29:near, func2A:near, func2B:near
  811. extrn func2C:near, func2D:near, func2E:near, func2F:near
  812. extrn func30:near, func31:near, func32:near, func33:near
  813. extrn func34:near, func35:near, func36:near, func37:near
  814. extrn func38:near, func39:near, func3A:near, func3B:near
  815. extrn func3C:near, func3D:near, func3E:near, func3F:near
  816. extrn func40:near, func41:near, func42:near, func43:near
  817. extrn func44:near, func45:near, func46:near, func47:near
  818. extrn func48:near, func49:near, func4A:near, func4B:near
  819. extrn func4C:near, func4D:near, func4E:near, func4F:near
  820. extrn func50:near, func51:near, func52:near, func53:near
  821. extrn func54:near, func55:near, func56:near, func57:near
  822. extrn func58:near, func59:near, func5A:near, func5B:near
  823. extrn func5C:near, func5D:near, func5E:near, func5F:near
  824. extrn func60:near, func62:near, func63:near, func65:near
  825. extrn func66:near, func67:near, func68:near, func69:near
  826. extrn func6C:near
  827. PCM_RODATA CSEG WORD
  828. Public pcmode_ft, pcmode_ftl
  829. pcmode_ft rw 0
  830. dw func00 ; (00) Terminate Program
  831. dw func01 ; (01) Read Keyboard and Echo
  832. dw func02 ; (02) Display Character
  833. dw func03 ; (03) Auxilary Input
  834. dw func04 ; (04) Auxilary Output
  835. dw func05 ; (05) Print Character
  836. dw func06 ; (06) Direct Console I/O
  837. dw func07 ; (07) Direct Console Input
  838. dw func08 ; (08) Read Keyboard
  839. dw func09 ; (09) Display String
  840. dw func0A ; (0A) Buffered Keyboard Input
  841. dw func0B ; (0B) Check Keyboard Status
  842. dw func0C ; (0C) Flush Buffer, Read Keyboard
  843. dw func0D ; (0D) Reset Disk
  844. dw func0E ; (0E) Select Disk
  845. dw func0F ; (0F) Open File
  846. dw func10 ; (10) Close File
  847. dw func11 ; (11) Search for First
  848. dw func12 ; (12) Search for Next
  849. dw func13 ; (13) Delete File
  850. dw func14 ; (14) Sequential Read
  851. dw func15 ; (15) Sequential Write
  852. dw func16 ; (16) Create File
  853. dw func17 ; (17) Rename File
  854. dw ms_zero_AL ; (18) Unused DOS function (AL = 0)
  855. dw func19 ; (19) Current Disk
  856. dw func1A ; (1A) Set Disk Transfer Address
  857. dw func1B ; (1B) *Get Default Drive Data
  858. dw func1C  ; (1C) *Get Drive Data
  859. dw ms_zero_AL ; (1D) Unused DOS function (AL = 0)
  860. dw ms_zero_AL ; (1E) Unused DOS function (AL = 0)
  861. dw func1F  ; (1F) Get Default DPB
  862. dw ms_zero_AL ; (20) Unused DOS function (AL = 0)
  863. dw func21 ; (21) Random Read
  864. dw func22 ; (22) Random Write
  865. dw func23 ; (23) File Size
  866. dw func24 ; (24) Set Relative Record
  867. dw func25 ; (25) Set Interrupt Vector
  868. dw func26 ; (26) Duplicate PSP
  869. dw func27 ; (27) Random Block Read
  870. dw func28 ; (28) Random Block Write
  871. dw func29 ; (29) Parse File Name
  872. dw func2A ; (2A) Get Date
  873. dw func2B ; (2B) Set Date
  874. dw func2C ; (2C) Get Time
  875. dw func2D ; (2D) Set Time
  876. dw func2E ; (2E) Set/Reset Verify Flag
  877. dw func2F ; (2F) Get Disk Transfer Address
  878. dw func30 ; (30) Get Version Number
  879. dw func31  ; (31) Keep Process
  880. dw func32 ; (32) Get DPB
  881. dw func33 ; (33) CONTROL-C Check
  882. dw func34 ; (34) Get the Indos Flag
  883. dw func35 ; (35) Get Interrupt Vector
  884. dw func36 ; (36) Get Disk Free Space
  885. dw func37 ; (37) Get/Set Switch Character
  886. dw func38 ; (38) Return Country Dependant Info
  887. dw func39 ; (39) Create Sub-directory
  888. dw func3A ; (3A) Remove Sub-directory
  889. dw func3B ; (3B) Change Sub-directory
  890. dw func3C ; (3C) Create a File
  891. dw func3D ; (3D) Open a File Handle
  892. dw func3E ; (3E) Close a File Handle
  893. dw func3F ; (3F) Read from a File/Device
  894. dw func40 ; (40) Write to a File/Device
  895. dw func41 ; (41) Delete a Directory Entry
  896. dw func42 ; (42) Move a File Pointer
  897. dw func43 ; (43) Change Attributes
  898. dw func44 ; (44) I/O Control
  899. dw func45 ; (45) Duplicate File Handle
  900. dw func46 ; (46) Force a Duplicate File Handle
  901. dw func47 ; (47) Return Text of Current Directory
  902. dw func48 ; (48) Allocate Memory
  903. dw func49 ; (49) Free Allocated Memory
  904. dw func4A ; (4A) Modify Allocated Memory
  905. dw func4B ; (4B) Load and Execute Program
  906. dw func4C ; (4C) Terminate a Process
  907. dw func4D ; (4D) Get Return Code
  908. dw func4E ; (4E) Find Matching File
  909. dw func4F ; (4F) Find Next Matching File
  910. dw func50 ; (50) Set Current PSP
  911. dw func51 ; (51) Get Current PSP
  912. dw func52 ; (52) *Get In Vars
  913. dw func53 ; (53) *Build DPB from BPB
  914. dw func54 ; (54) Return Verify State
  915. dw func55 ; (55) Create a New PSP
  916. dw func56 ; (56) Move a Directory Entry
  917. dw func57 ; (57) Get/Set File Date and Time
  918. dw func58 ; (58) Memory Allocation Strategy
  919. dw func59 ; (59) Get Extended Error
  920. dw func5A ; (5A) Create Temporary File
  921. dw func5B ; (5B) Create New File
  922. dw func5C ; (5C) File Lock Control
  923. dw func5D ; (5D) Internal DOS Function
  924. dw func5E ; (5E) Control Local Machine Data
  925. dw func5F ; (5F) Get Network Assignments
  926. dw func60 ; (60) Perform Name Processing
  927. dw ms_zero_AL ; (61) ?? Parse Path (AL = 0)
  928. dw func62 ; (62) Get Current PSP
  929. dw func63 ; (63) Get Lead Byte Table
  930. dw invalid_function ; (64) *Saves AL and Returns
  931. dw func65 ; (65) Get Extended Country Information
  932. dw func66 ; (66) Get/Set Global Code Page
  933. dw func67 ; (67) Set Handle Count
  934. dw func68 ; (68) Commit File
  935. dw func69 ; (69) Get Serial number
  936. dw func68 ; (6A) Commit File (again)
  937. dw invalid_function ; (6B) Unknown DOS 4
  938. dw func6C ; (6C) Extended Open/Create
  939. pcmode_ftl equ (offset $ - offset pcmode_ft)/2
  940. ;**************************
  941. ;* Do Not Move This Entry *
  942. ;**************************
  943. dw ms_zero_AL ; Illegal Function Handler
  944. end