Source code of Windows XP (NT5)
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.

3567 lines
127 KiB

  1. PAGE ,132
  2. TITLE DXINTR.ASM -- Dos Extender Interrupt Reflector
  3. ; Copyright (c) Microsoft Corporation 1988-1991. All Rights Reserved.
  4. ;****************************************************************
  5. ;* *
  6. ;* DXINTR.ASM - Dos Extender Interrupt Reflector *
  7. ;* *
  8. ;****************************************************************
  9. ;* *
  10. ;* Revision History: *
  11. ;* *
  12. ;* *
  13. ;* 09/13/90 earleh Fault handlers Ring 0 *
  14. ;* 09/06/90 earleh Fault handlers DPMI compliant *
  15. ;* PIC remapping no longer required *
  16. ;* 08/08/90 earleh DOSX and client privilege ring determined *
  17. ;* by equate in pmdefs.inc *
  18. ;* 05/09/90 jimmat Started VCPI changes. *
  19. ;* 04/02/90 jimmat Added PM Int 70h handler. *
  20. ;* 01/08/90 jimmat Don't allow nested PS/2 mouse interrupts *
  21. ;* (later removed!) *
  22. ;* 09/15/89 jimmat Support for 'Classic' HP Vectras which *
  23. ;* have 3 8259 interrupt controllers *
  24. ;* 07/28/89 jimmat Save A20 state when reflecting an int to *
  25. ;* protected mode, removed Int 30h handler *
  26. ;* that did code patch-ups, point debugger *
  27. ;* to faulting instruction, not Int 3. *
  28. ;* 07/13/89 jimmat Improved termination due to faults when *
  29. ;* not running under a debugger--also ifdef'd *
  30. ;* out code to dynamically fixup code seg *
  31. ;* references on GP faults *
  32. ;* 06/05/89 jimmat Ints 0h-1Fh are now vectored through a 2nd *
  33. ;* table. This allows Wdeb386 interaction *
  34. ;* more like Windows/386. *
  35. ;* 05/23/89 jimmat Added wParam & lParam to interrupt frame. *
  36. ;* 05/07/89 jimmat Added XMScontrol function to map protected *
  37. ;* mode XMS requests to real mode driver. *
  38. ;* 05/02/89 jimmat 8259 interrupt mask saved around changing *
  39. ;* of hardware interrupt base *
  40. ;* 04/24/89 jimmat Added support for PS/2 Int 15h/C2h/07 Set *
  41. ;* Pointing Device Handler Address function *
  42. ;* 04/12/89 jimmat Added PMIntr24 routine to support PM *
  43. ;* Critical Error Handlers *
  44. ;* 03/15/89 jimmat Added INT 31h LDT/heap interface a la *
  45. ;* Windows/386 *
  46. ;* 03/14/89 jimmat Changes to run child in ring 1 with LDT *
  47. ;* 02/24/89 (GeneA): fixed problem in IntEntryVideo and *
  48. ;* IntExitVideo for processing function 10h subfunction *
  49. ;* for reading and writing the VGA palette. *
  50. ;* 02/22/89 (GeneA): added handlers for Int 10h, Int 15h, and *
  51. ;* Int 33h. Added support for more general mechanism for *
  52. ;* handling interrupts require special servicing and *
  53. ;* allowing nesting of these interrupts. Allocation and *
  54. ;* deallocation of stack frames is supported to allow *
  55. ;* nested paths through the interrupt reflection code to *
  56. ;* a depth of 8. *
  57. ;* There is still a problem that if an interrupt handler *
  58. ;* is using a static buffer to transfer data, another *
  59. ;* interrupt that uses the same static buffer could come *
  60. ;* in and trash it. Solving the problem in a completely *
  61. ;* general way would require having a buffer allocation *
  62. ;* deallocation scheme for doing the transfers between *
  63. ;* real mode memory and protected mode memory. *
  64. ;* 02/14/89 (GeneA): added code in TrapGP to print error msg *
  65. ;* and quit when running a non-debugging version. *
  66. ;* 02/10/89 (GeneA): changed Dos Extender from small model to *
  67. ;* medium model. Added function LoaderTrap to handle *
  68. ;* loader interrupts when the program contains overlays. *
  69. ;* 11/20/88 (GeneA): changed both RM and PM interrupt reflector*
  70. ;* routines to pass the flags returned by the ISR back to *
  71. ;* the originator of the interrupt, rather than returning *
  72. ;* the original flags. *
  73. ;* 10/28/88 (GeneA): created *
  74. ; 18-Dec-1992 sudeepb Changed cli/sti to faster FCLI/FSTI
  75. ;* *
  76. ;****************************************************************
  77. .286p
  78. .287
  79. ; -------------------------------------------------------
  80. ; INCLUDE FILE DEFINITIONS
  81. ; -------------------------------------------------------
  82. .xlist
  83. .sall
  84. include segdefs.inc
  85. include gendefs.inc
  86. include pmdefs.inc
  87. include interupt.inc
  88. ifdef WOW_x86
  89. include vdmtib.inc
  90. endif
  91. .list
  92. include intmac.inc
  93. include stackchk.inc
  94. include bop.inc
  95. include dpmi.inc
  96. ; -------------------------------------------------------
  97. ; GENERAL SYMBOL DEFINITIONS
  98. ; -------------------------------------------------------
  99. ; -------------------------------------------------------
  100. ; EXTERNAL SYMBOL DEFINITIONS
  101. ; -------------------------------------------------------
  102. extrn EnterRealMode:NEAR
  103. extrn EnterProtectedMode:NEAR
  104. extrn ParaToLinear:NEAR
  105. externFP NSetSegmentDscr
  106. ifdef NEC_98
  107. extrn GetSegmentAddress:NEAR
  108. endif ;NEC_98
  109. extrn ParaToLDTSelector:NEAR
  110. ; -------------------------------------------------------
  111. ; DATA SEGMENT DEFINITIONS
  112. ; -------------------------------------------------------
  113. DXDATA segment
  114. extrn pmusrss:WORD
  115. extrn pmusrsp:WORD
  116. extrn npXfrBuf1:WORD
  117. extrn rgbXfrBuf0:BYTE
  118. extrn rgbXfrBuf1:BYTE
  119. extrn lpfnXMSFunc:DWORD
  120. extrn Int28Filter:WORD
  121. extrn DpmiFlags:WORD
  122. IFDEF WOW_x86
  123. extrn FastBop:fword
  124. ENDIF
  125. ;
  126. ; Variables used to store register values while mode switching.
  127. public regUserSS, regUserSP, regUserFL, regUserAX, regUserDS
  128. public regUserES
  129. regUserSS dw ?
  130. regUserSP dw ?
  131. regUserCS dw ?
  132. regUserIP dw ?
  133. regUserFL dw ?
  134. regUserAX dw ?
  135. regUserDS dw ?
  136. regUserES dw ?
  137. pfnReturnAddr dw ?
  138. Int28Count dw -1 ;Count of idle Int 28h's not reflected to RM
  139. ;
  140. ; Far pointer to the user's mouse callback function.
  141. public lpfnUserMouseHandler
  142. lpfnUserMouseHandler dd 0 ;Entry point to the users mouse handler
  143. cbMouseState dw 0 ;size of mouse state buffer in bytes
  144. ; Far pointer to PS/2 Pointing device handler address
  145. public lpfnUserPointingHandler
  146. lpfnUserPointingHandler dd 0 ;Sel:Off to user's handler
  147. align 2
  148. if DEBUG
  149. extrn StackGuard:WORD
  150. endif
  151. extrn pbReflStack:WORD
  152. extrn bReflStack:WORD
  153. ;
  154. ; This buffer contains the original real mode interrupt vectors.
  155. ifdef NEC_98
  156. public rglpfnRmISR
  157. endif ;NEC_98
  158. align 2
  159. rglpfnRmISR dd 256 dup (?)
  160. ; PMFaultVector is a table of selector:offsets for routines to process
  161. ; protected mode processor faults/traps/exceptions. If we don't handle
  162. ; the exception as an exception, we vector it through PMReservedEntryVector.
  163. FltRtn macro off
  164. dw DXPMCODE:off
  165. dw 0
  166. dw SEL_DXPMCODE or STD_RING
  167. dw 0
  168. endm
  169. public PMFaultVector
  170. align 4
  171. PMFaultVector label DWORD
  172. FltRtn PMFaultEntryVector+5*0h ; int 0
  173. FltRtn PMFaultEntryVector+5*1h ; int 1
  174. FltRtn PMFaultEntryVector+5*2h ; int 2
  175. FltRtn PMFaultEntryVector+5*3h ; int 3
  176. FltRtn PMFaultEntryVector+5*4h ; int 4
  177. FltRtn PMFaultEntryVector+5*5h ; int 5
  178. FltRtn PMFaultEntryVector+5*6h ; int 6
  179. FltRtn PMFaultEntryVector+5*7h ; int 7
  180. FltRtn PMFaultEntryVector+5*8h ; int 8
  181. FltRtn PMFaultEntryVector+5*9h ; int 9
  182. FltRtn PMFaultEntryVector+5*0Ah ; int a
  183. FltRtn PMFaultEntryVector+5*0Bh ; int b
  184. FltRtn PMFaultEntryVector+5*0Ch ; int c
  185. FltRtn PMFaultEntryVector+5*0Dh ; int d
  186. FltRtn PMFaultEntryVector+5*0Eh ; int e
  187. FltRtn PMFaultEntryVector+5*0Fh ; int f
  188. FltRtn PMFaultEntryVector+5*10h ; int 10h
  189. FltRtn PMFaultEntryVector+5*11h ; int 11h
  190. FltRtn PMFaultEntryVector+5*12h ; int 12h
  191. FltRtn PMFaultEntryVector+5*13h ; int 13h
  192. FltRtn PMFaultEntryVector+5*14h ; int 14h
  193. FltRtn PMFaultEntryVector+5*15h ; int 15h
  194. FltRtn PMFaultEntryVector+5*16h ; int 16h
  195. FltRtn PMFaultEntryVector+5*17h ; int 17h
  196. FltRtn PMFaultEntryVector+5*18h ; int 18h
  197. FltRtn PMFaultEntryVector+5*19h ; int 19h
  198. FltRtn PMFaultEntryVector+5*1Ah ; int 1ah
  199. FltRtn PMFaultEntryVector+5*1Bh ; int 1bh
  200. FltRtn PMFaultEntryVector+5*1Ch ; int 1ch
  201. FltRtn PMFaultEntryVector+5*1Dh ; int 1Dh
  202. FltRtn PMFaultEntryVector+5*1Eh ; int 1Eh
  203. FltRtn PMFaultEntryVector+5*1Fh ; int 1Fh
  204. extrn npEHStackLimit:word
  205. extrn npEHStacklet:word
  206. ifdef NEC_98
  207. extrn fPCH98:BYTE
  208. endif ;NEC_98
  209. IFDEF WOW
  210. public Wow16BitHandlers
  211. Wow16BitHandlers dw 256 dup (0,0)
  212. ENDIF
  213. DXDATA ends
  214. DXSTACK segment
  215. public rgw0Stack, rgw2FStack
  216. dw 64 dup (?) ; INT 2Fh handler stack
  217. rgw2FStack label word
  218. dw 64 dup (?) ; DOSX Ring -> Ring 0 transition stack
  219. ;
  220. ; Interrupts in the range 0-1fh cause a ring transition and leave
  221. ; an outer ring IRET frame right here.
  222. ;
  223. Ring0_EH_DS dw ? ; place to put user DS
  224. Ring0_EH_AX dw ? ; place to put user AX
  225. Ring0_EH_BX dw ? ; place to put user BX
  226. Ring0_EH_CX dw ? ; place to put user CX
  227. Ring0_EH_BP dw ? ; place to put user BP
  228. Ring0_EH_PEC dw ? ; lsw of error code for 386 page fault
  229. ; also near return to PMFaultEntryVector
  230. Ring0_EH_EC dw ? ; error code passed to EH
  231. Ring0_EH_IP dw ? ; interrupted code IP
  232. Ring0_EH_EIP dw ? ; high half eip
  233. Ring0_EH_CS dw ? ; interrupted code CS
  234. dw ? ; high half of cs
  235. Ring0_EH_Flags dw ? ; interrupted code flags
  236. Ring0_EH_EFlags dw ? ; high half of flags
  237. Ring0_EH_SP dw ? ; interrupted code SP
  238. Rin0_EH_ESP dw ? ; high half of esp
  239. Ring0_EH_SS dw ? ; interrupted code SS
  240. dw ? ; high half of ss
  241. rgw0Stack label word
  242. dw 64 dup (?) ; stack for switching to ring0
  243. public ResetStack
  244. ResetStack label word
  245. ifdef WOW_x86
  246. dw 64 dup (?) ; wow stack for initial int field
  247. public rgwWowStack
  248. rgwWowStack label word
  249. endif
  250. DXSTACK ends
  251. ; -------------------------------------------------------
  252. ; CODE SEGMENT VARIABLES
  253. ; -------------------------------------------------------
  254. DXCODE segment
  255. extrn selDgroup:WORD
  256. DXCODE ends
  257. DXPMCODE segment
  258. extrn selDgroupPM:WORD
  259. extrn segDXCodePM:WORD
  260. extrn RZCall:NEAR
  261. extrn segDXDataPM:WORD
  262. DXPMCODE ends
  263. ; -------------------------------------------------------
  264. page
  265. subttl Protected Mode Interrupt Reflector
  266. ; -------------------------------------------------------
  267. ; PROTECTED MODE INTERRUPT REFLECTOR
  268. ; -------------------------------------------------------
  269. DXPMCODE segment
  270. assume cs:DXPMCODE
  271. ; -------------------------------------------------------
  272. ; PMIntrEntryVector -- This table contains a vector of
  273. ; near jump instructions to the protected mode interrupt
  274. ; reflector. The protected mode interrupt descriptor
  275. ; table is initialized so that all interrupts jump to
  276. ; locations in this table, which transfers control to
  277. ; the interrupt reflection code for reflecting the
  278. ; interrupt to real mode.
  279. StartBopTable macro
  280. ?intr = 0
  281. endm
  282. PMIntrBop macro
  283. DPMIBOP ReflectIntrToV86
  284. db ?intr
  285. ?intr = ?intr+1
  286. endm
  287. public PMIntrEntryVector
  288. PMIntrEntryVector:
  289. StartBopTable
  290. rept 256
  291. PMIntrBop
  292. endm
  293. FaultBop macro
  294. DPMIBOP DpmiUnhandledException
  295. db ?intr
  296. ?intr = ?intr+1
  297. endm
  298. public PMFaultEntryVector
  299. ; -------------------------------------------------------
  300. ; PMFaultEntryVector -- This table contains a vector of
  301. ; near jump instructions to the protected mode fault
  302. ; analyzer.
  303. ;
  304. PMFaultEntryVector:
  305. StartBopTable
  306. rept 32
  307. FaultBop
  308. endm
  309. assume ds:nothing,es:nothing,ss:nothing
  310. public PMFaultHandlerIRET
  311. PMFaultHandlerIRET:
  312. DPMIBOP FaultHandlerIret
  313. public PMFaultHandlerIRETD
  314. PMFaultHandlerIRETD:
  315. DPMIBOP FaultHandlerIretd
  316. public PMIntHandlerIRET
  317. PMIntHandlerIRET:
  318. DPMIBOP IntHandlerIret
  319. public PMIntHandlerIRETD
  320. PMIntHandlerIRETD:
  321. DPMIBOP IntHandlerIretd
  322. public PMDosxIret
  323. PMDosxIret:
  324. iret
  325. public PMDosxIretd
  326. PMDosxIretd:
  327. db 66h
  328. iret
  329. public HungAppExit
  330. HungAppExit:
  331. mov ax,4CFFh
  332. int 21h
  333. ; -------------------------------------------------------
  334. DXPMCODE ends
  335. ; -------------------------------------------------------
  336. subttl Real Mode Interrupt Reflector
  337. page
  338. ; -------------------------------------------------------
  339. ; REAL MODE INTERRUPT REFLECTOR
  340. ; -------------------------------------------------------
  341. DXCODE segment
  342. assume cs:DXCODE
  343. ; -------------------------------------------------------
  344. ; RMIntrEntryVector -- This table contains a vector of
  345. ; near jump instructions to the real mode interrupt
  346. ; reflector. Real mode interrupts that have been hooked
  347. ; by the protected mode application have their vector
  348. ; set to entry the real mode reflector through this table.
  349. public RMtoPMReflector
  350. RMtoPMReflector:
  351. DPMIBOP ReflectIntrToPM
  352. public RMCallBackBop
  353. RMCallBackBop proc far
  354. DPMIBOP RMCallBackCall
  355. ret ;finished!
  356. RMCallBackBop endp
  357. DXCODE ends
  358. ; -------------------------------------------------------
  359. subttl INT 24h Critical Error Mapper
  360. page
  361. ; -------------------------------------------------------
  362. ; DOS CRITICAL ERROR MAPPER
  363. ; -------------------------------------------------------
  364. DXCODE segment
  365. ; -------------------------------------------------------
  366. ; RMDefaultInt24Handler -- Default action for a DOS critical
  367. ; error is to fail the call.
  368. ;
  369. public RMDefaultInt24Handler
  370. RMDefaultInt24Handler proc far
  371. mov al,3
  372. iret
  373. RMDefaultInt24Handler endp
  374. DXCODE ends
  375. ; -------------------------------------------------------
  376. subttl INT 28h Idle Handler
  377. page
  378. ; -------------------------------------------------------
  379. ; INT 28H IDLE HANDLER
  380. ; -------------------------------------------------------
  381. DXPMCODE segment
  382. assume cs:DXPMCODE
  383. ; -------------------------------------------------------
  384. ; PMIntr28 -- Protected mode handler for Idle Int 28h calls.
  385. ; The purpose of this routine is simply to cut down on the
  386. ; number of protected mode to real mode switches by ignoring
  387. ; many of the Int 28h idle calls made by the Windows PM
  388. ; kernel.
  389. assume ds:NOTHING,es:NOTHING,ss:NOTHING
  390. public PMIntr28
  391. PMIntr28 proc near
  392. cld
  393. push ds ;address our DGROUP
  394. mov ds,selDgroupPM
  395. assume ds:DGROUP
  396. cmp Int28Filter,0 ;are we passing any through?
  397. jz @f
  398. inc Int28Count ;should this one be reflected?
  399. jz i28_reflect
  400. @@:
  401. pop ds
  402. iret ; no, just ignore it
  403. i28_reflect: ; yes, reset count and
  404. push ax ; reflecto to real mode
  405. mov ax,Int28Filter
  406. neg ax
  407. mov Int28Count,ax
  408. pop ax
  409. pop ds
  410. assume ds:NOTHING
  411. jmp PMIntrEntryVector + 5*28h
  412. PMIntr28 endp
  413. ; -------------------------------------------------------
  414. ; PMIntr31 -- Service routine for the Protect Mode INT 31h
  415. ; services. These functions duplicate the
  416. ; Windows/386 VMM INT 31h services for protected
  417. ; mode applications. They were implemented to
  418. ; support a protect mode version of Windows/286.
  419. ;
  420. ; Input: Various registers
  421. ; Output: Various registers
  422. ; Errors:
  423. ; Uses: All registers preserved, other than return values
  424. assume ds:NOTHING,es:NOTHING,ss:NOTHING
  425. public PMIntr31
  426. PMIntr31 proc near
  427. push ds
  428. push ax
  429. mov ax,SEL_DXDATA OR STD_RING
  430. mov ds,ax
  431. assume ds:DGROUP
  432. pop ax
  433. FBOP BOP_DPMI,Int31Entry,FastBop
  434. int 3
  435. ; This BOP does an implicit IRET
  436. PMIntr31 endp
  437. ; -------------------------------------------------------
  438. subttl Ignore Interrupt Handlers
  439. page
  440. ; -------------------------------------------------------
  441. ; IGNORE INTERRUPT HANDLER
  442. ; -------------------------------------------------------
  443. ; PMIntrIgnore -- Service routine for protected mode interrupts
  444. ; that should be ignored, and not reflected to real mode.
  445. ; Currently used for:
  446. ;
  447. ; Int 30h - used to be Win/386 Virtualize I/O, now
  448. ; unused but no int handler in real mode
  449. ; Int 41h - Wdeb386 interface, no int handler in
  450. ; real mode
  451. assume ds:NOTHING,es:NOTHING,ss:NOTHING
  452. public PMIntrIgnore
  453. PMIntrIgnore proc near
  454. iret
  455. PMIntrIgnore endp
  456. ; -------------------------------------------------------
  457. public PMIntr19
  458. PMIntr19 proc near
  459. push offset DXPMCODE:Reboot
  460. call RZCall
  461. bpRebootIDT df 0
  462. Reboot:
  463. mov ax,40h
  464. mov es,ax
  465. mov word ptr es:[0072h],1234h
  466. lidt bpRebootIDT
  467. int 3
  468. PMIntr19 endp
  469. DXPMCODE ends
  470. ; -------------------------------------------------------
  471. subttl XMS Driver Interface
  472. page
  473. ; -------------------------------------------------------
  474. DXPMCODE segment
  475. assume cs:DXPMCODE
  476. ; -------------------------------------------------------
  477. ; XMScontrol - This function implements a protected mode
  478. ; interface to a real mode XMS driver. Unlike other
  479. ; routines in this module, this routine is called by
  480. ; the user, not invoked via an INT instruction.
  481. ;
  482. ; Input: User's regs for XMS driver
  483. ; Output: regs from XMS driver
  484. ; Uses: none
  485. assume ds:NOTHING,es:NOTHING,ss:NOTHING
  486. public XMScontrol
  487. XMScontrol proc far
  488. jmp short XMSentry ;'standard' XMS control function
  489. nop ; just to be consistant
  490. nop
  491. nop
  492. XMSentry:
  493. ; Modify the stack so it looks like we got here via an INT (except that
  494. ; we may still have interrupts enabled)
  495. pushf
  496. cld
  497. push bp
  498. mov bp,sp ;bp -> [BP] [FL] [IP] [CS]
  499. push ax
  500. push bx
  501. mov ax,[bp+4]
  502. mov bx,[bp+6]
  503. xchg ax,[bp+2]
  504. mov [bp+4],bx
  505. mov [bp+6],ax ;bp -> [BP] [IP] [CS] [FL]
  506. pop bx
  507. pop ax
  508. pop bp
  509. ; We don't support XMS function 0Bh (Move Extended Memory Block) because
  510. ; it requires mapping of data between hi/low memory. Maybe someday...
  511. cmp ah,0Bh
  512. jnz xms_2
  513. xms_deny:
  514. xor ax,ax ;if function 0Bh, return failure
  515. mov bl,80h ; (ax = 0, bl = 80h-not implemented)
  516. jmp short XMSret
  517. xms_2:
  518. ; We are not really an Int handler, but close enough...
  519. call EnterIntHandler ;build an interrupt stack frame
  520. assume ds:DGROUP,es:DGROUP ; also sets up addressability
  521. SwitchToRealMode
  522. pop es ;load regs for driver
  523. pop ds
  524. assume ds:NOTHING,es:NOTHING,ss:DGROUP
  525. popa
  526. npopf
  527. call lpfnXMSFunc ;call real mode driver
  528. pushf ;rebuild stack frame
  529. FCLI
  530. cld
  531. pusha
  532. push ds
  533. push es
  534. mov bp,sp ;restore stack frame pointer
  535. SwitchToProtectedMode
  536. assume ds:DGROUP,es:DGROUP
  537. call LeaveIntHandler
  538. assume ds:NOTHING,es:NOTHING,ss:NOTHING
  539. XMSret:
  540. riret
  541. XMScontrol endp
  542. ; -------------------------------------------------------
  543. DXPMCODE ends
  544. ; -------------------------------------------------------
  545. subttl Special Interrupt Handler Routines
  546. page
  547. ; -------------------------------------------------------
  548. ;
  549. ; The following sets of routines handle interrupts that
  550. ; are function call interfaces and require special servicing
  551. ; by the Dos Extender. These interrupts are such things as
  552. ; the mouse driver function call interrupt, various PC BIOS
  553. ; function call interrupts, etc. Note that INT 21h (the Dos
  554. ; function call interrupt) is not handled here. These
  555. ; interrupts typically require that register values be modified
  556. ; and parameter data be copied between real mode memory and
  557. ; extended memory. The following conventions are used for these
  558. ; interrupt function handler routines.
  559. ;
  560. ; A stack is allocated from the interrupt reflector stack for these
  561. ; routines to use. This allows nested servicing of interrupts.
  562. ; A stack frame is built in the allocated stack which contains the
  563. ; following information:
  564. ; original caller's stack address
  565. ; caller's original flags and general registers (in pusha form)
  566. ; caller's original segment registers (DS & ES)
  567. ; flags and general registers to be passed to interrupt routine
  568. ; (initially the same as caller's original values)
  569. ; segment registers (DS & ES) to be passed to interrupt routine
  570. ; (initially set to the Dos Extender data segment address)
  571. ; This stack frame is built by the routine EnterIntHandler, and its
  572. ; format is defined by the structure INTRSTACK. The stack frame is
  573. ; destroyed and the processor registers set up for return to the user
  574. ; by the function LeaveIntHandler.
  575. ;
  576. ; For each interrupt, there is an entry function and an exit function.
  577. ; The entry function performs any modifications to parameter values and
  578. ; data buffering necessary before the interrupt service routine is called.
  579. ; The exit function performs any data buffering and register value
  580. ; modifications after return from the interrupt service routine.
  581. ;
  582. ; There are two sets of general registers and two sets of segment
  583. ; registers (DS & ES) on the stack frame. One set of register values
  584. ; has member names of the form intUserXX. The values in these stack
  585. ; frame members will be passed to the interrupt service routine when
  586. ; it is called, and will be loaded with the register values returned
  587. ; by the interrupt service routine. The other set of registers values
  588. ; has member names of the form pmUserXX. These stack frame members
  589. ; contain the original values in the registers on entry from the
  590. ; user program that called the interrupt.
  591. ;
  592. ; When we return to the original caller, we want to pass back the
  593. ; general registers as returned by the interrupt routine (and possibly
  594. ; modified by the exit handler), and the same segment registers as
  595. ; on entry, unless the interrupt routine returns a value in a segment
  596. ; register. (in this case, there must be some code in the exit routine
  597. ; to handle this). This means that when we return to the caller, we
  598. ; return the general register values from the intUserXX set of stack
  599. ; frame members, but we return the segment registers from the pmUserXX
  600. ; set of frame members. By doing it this way, we don't have to do
  601. ; any work for the case where the interrupt subfuntion doesn't require
  602. ; any parameter manipulation. NOTE however, this means that when
  603. ; manipulating register values to be returned to the user, the segment
  604. ; registers are treated opposite to the way the general registers are
  605. ; treated. For general registers, to return a value to the user,
  606. ; store it in a intUserXX stack frame member. To return a segment
  607. ; value to the user, store it in a pmUserXX stack frame member.
  608. ;
  609. ; -------------------------------------------------------
  610. subttl BIOS Video Interrupt (Int 10h) Service Routine
  611. page
  612. ; -------------------------------------------------------
  613. ; BIOS VIDEO INTERRUPT (INT 10h) SERVICE ROUTINE
  614. ; -------------------------------------------------------
  615. DXPMCODE segment
  616. assume cs:DXPMCODE
  617. ; -------------------------------------------------------
  618. ; PMIntrVideo - Entry point into interrupt reflector code
  619. ; for IBM PC Bios video (int 10h) calls.
  620. ;
  621. ; Input: normal registers for Bios calls
  622. ; Output: normal register returns for Bios calls
  623. ; Errors: normal Bios errors
  624. ; Uses: as per Bios calls
  625. assume ds:NOTHING,es:NOTHING,ss:NOTHING
  626. public PMIntrVideo
  627. PMIntrVideo:
  628. ifdef NEC_98
  629. cmp ah,40h
  630. jb CRT_bios
  631. cmp ah,4Fh ;4Bh-4Fh = Reserve
  632. ja CRT_bios
  633. jmp PMIntrGBIO
  634. CRT_bios:
  635. call EnterIntHandler ;build a stack frame and fix up the
  636. cld ; return address so that the interrupt
  637. ;service routine will return to us.
  638. ;
  639. ; Perform fixups on the entry register values
  640. call IntEntryVideo
  641. @@:
  642. ; Execute the interrupt service routine
  643. SwitchToRealMode
  644. assume ss:DGROUP
  645. pop es
  646. pop ds
  647. assume ds:NOTHING,es:NOTHING
  648. popa
  649. call rglpfnRmISR[4*18h] ;execute the real mode interrupt routine
  650. pushf
  651. cli
  652. cld
  653. pusha
  654. push ds
  655. push es
  656. mov bp,sp ;restore stack frame pointer
  657. SwitchToProtectedMode
  658. assume ds:DGROUP,es:DGROUP
  659. ;
  660. ; Perform fixups on the return register values.
  661. mov ax,[bp].pmUserAX ;get original function code
  662. ;; test fPCH98,0FFh
  663. ;; jz NotNPCVideoExit ;for PC-H98 modelxx
  664. ;; call IntExitVideoNPC ; "
  665. ;; jmp @f ; "
  666. ;;NotNPCVideoExit: ; "
  667. call IntExitVideo
  668. @@:
  669. ;
  670. ; And return to the original caller.
  671. call LeaveIntHandler
  672. iret
  673. ;/////////////////////////////////////////////////////////////////////////
  674. ; Nmode GRAPH BIOS
  675. ;/////////////////////////////////////////////////////////////////////////
  676. ; -------------------------------------------------------
  677. ; PMIntrGBIO
  678. ;--------------------------------------------------------
  679. assume ds:NOTHING,es:NOTHING,ss:NOTHING
  680. public PMIntrGBIO
  681. PMIntrGBIO:
  682. call EnterIntHandler ;build a stack frame and fix up the
  683. cld ; return address so that the interrupt
  684. ;service routine will return to us.
  685. ;
  686. ; Perform fixups on the entry register values
  687. push ax
  688. mov ax,[bp].pmUserDS
  689. call GetSegmentAddress
  690. shr dx,4
  691. shl bx,12
  692. or bx,dx ;bx now = seg of parent psp
  693. mov [bp].intUserDS,bx
  694. pop ax
  695. ;
  696. ; Execute the interrupt service routine
  697. SwitchToRealMode
  698. assume ss:DGROUP
  699. pop es
  700. pop ds
  701. assume ds:NOTHING,es:NOTHING
  702. popa
  703. call rglpfnRmISR[4*18h] ;execute the real mode interrupt routine
  704. pushf
  705. cli
  706. cld
  707. pusha
  708. push ds
  709. push es
  710. mov ax,ss
  711. mov ds,ax
  712. mov es,ax
  713. mov bp,sp ;restore stack frame pointer
  714. SwitchToProtectedMode
  715. assume ds:DGROUP,es:DGROUP
  716. ;
  717. ; Perform fixups on the return register values.
  718. mov ax,[bp].pmUserAX ;get original function code
  719. push ax
  720. mov ax,[bp].pmUserDS
  721. mov [bp].intUserDS,ax
  722. pop ax
  723. ;
  724. ; And return to the original caller.
  725. call LeaveIntHandler
  726. iret
  727. else ;!NEC_98
  728. call EnterIntHandler ;build a stack frame and fix up the
  729. cld ; return address so that the interrupt
  730. ;service routine will return to us.
  731. ;
  732. ; Perform fixups on the entry register values
  733. call IntEntryVideo
  734. ;
  735. ; Execute the interrupt service routine
  736. SwitchToRealMode
  737. assume ss:DGROUP
  738. pop es
  739. pop ds
  740. assume ds:NOTHING,es:NOTHING
  741. popa
  742. sub sp,8 ; make room for stack frame
  743. push bp
  744. mov bp,sp
  745. push es
  746. push ax
  747. xor ax,ax
  748. mov es,ax
  749. mov [bp + 8],cs
  750. mov word ptr [bp + 6],offset piv_10
  751. mov ax,es:[10h*4]
  752. mov [bp + 2],ax
  753. mov ax,es:[10h*4 + 2]
  754. mov [bp + 4],ax
  755. pop ax
  756. pop es
  757. pop bp
  758. retf
  759. piv_10: pushf
  760. FCLI
  761. cld
  762. pusha
  763. push ds
  764. push es
  765. mov bp,sp ;restore stack frame pointer
  766. SwitchToProtectedMode
  767. assume ds:DGROUP,es:DGROUP
  768. ;
  769. ; Perform fixups on the return register values.
  770. mov ax,[bp].pmUserAX ;get original function code
  771. call IntExitVideo
  772. ;
  773. ; And return to the original caller.
  774. call LeaveIntHandler
  775. riret
  776. endif ;!NEC_98
  777. ; -------------------------------------------------------
  778. ; IntEntryVideo -- This routine performs any register
  779. ; fixups and data copying needed on entry to the
  780. ; PC BIOS video interrupt (Int 10h)
  781. ;
  782. ; Input: register values on stack frame
  783. ; Output: register values on stack frame
  784. ; Errors: none
  785. ; Uses: any registers modified,
  786. ; possibly modifies buffers rgbXfrBuf0 or rgbXfrBuf1
  787. assume ds:DGROUP,es:DGROUP,ss:NOTHING
  788. public IntEntryVideo
  789. IntEntryVideo:
  790. ifdef NEC_98
  791. ;video mode
  792. cmp ah,0Fh
  793. jnz ienv10
  794. mov cx,16
  795. jmp ienv70
  796. ienv10:
  797. cmp ah,14h
  798. jnz ienv20
  799. jmp ienv80
  800. ienv20:
  801. cmp ah,1Fh
  802. jnz ienv30
  803. jmp ienv110
  804. ienv30:
  805. cmp ah,1Ah
  806. jnz ienv40
  807. test fPCH98,0FFh
  808. jnz H98_FontWrite_N
  809. mov cx,34
  810. jmp ienv70
  811. ienv40:
  812. cmp ah,20h
  813. jnz ienv90
  814. test fPCH98,0FFh
  815. jnz @f
  816. mov cx,72
  817. jmp ienv100
  818. @@:
  819. jmp H98_FontWrite_H
  820. ienv70:
  821. push ds
  822. mov si,[bp].pmUserCX ;offset address
  823. mov ds,[bp].pmUserBX ;segment address
  824. mov di,offset DGROUP:rgbXfrBuf1
  825. cld
  826. rep movsb
  827. pop ds
  828. ienv80:
  829. push ax
  830. mov ax,segDXDataPM
  831. mov [bp].intUserBX,ax ;segment address
  832. pop ax
  833. mov [bp].intUserCX,offset DGROUP:rgbXfrBuf1
  834. ienv90:
  835. ret
  836. ienv100:
  837. push ds
  838. mov si,[bp].pmUserBX ;offset address
  839. mov ds,[bp].pmUserDS ;segment address
  840. mov di,offset DGROUP:rgbXfrBuf1
  841. cld
  842. rep movsb
  843. pop ds
  844. ienv110:
  845. push ax
  846. mov ax,segDXDataPM
  847. mov [bp].intUserDS,ax ;segment address
  848. pop ax
  849. mov [bp].intUserBX,offset DGROUP:rgbXfrBuf1
  850. ienv120:
  851. ret
  852. H98_FontWrite_N:
  853. cmp dx,7601h
  854. jb @f
  855. cmp dx,767Fh
  856. jna WUSKZEN
  857. cmp dx,7701h
  858. jb @f
  859. cmp dx,777Fh
  860. jna WUSKZEN
  861. cmp dx,7801h
  862. jb @f
  863. cmp dx,783Fh
  864. ;;;;;;;; ja ienv35
  865. jna WUSKZEN
  866. jmp ienv35
  867. WUSKZEN:
  868. mov cx,34
  869. jmp ienv70
  870. @@:
  871. jmp ienv40
  872. ienv35:
  873. cmp dx,7840h
  874. jb @b
  875. cmp dx,787Fh
  876. jna WUSKHAN
  877. cmp dx,7D01h
  878. jb @b
  879. cmp dx,7D7Fh
  880. jna WUSKHAN
  881. cmp dx,7E01h
  882. jb @b
  883. cmp dx,7E7Fh
  884. ;;;;;;;; ja @b
  885. jna WUSKHAN
  886. jmp @b
  887. WUSKHAN:
  888. mov cx,18
  889. jmp ienv70
  890. H98_FontWrite_H:
  891. cmp dx,7601h
  892. jb @f
  893. cmp dx,767Fh
  894. jna HWUSKZEN
  895. cmp dx,7701h
  896. jb @f
  897. cmp dx,777Fh
  898. jna HWUSKZEN
  899. cmp dx,7801h
  900. jb @f
  901. cmp dx,783Fh
  902. ;;;;;;;; ja @f
  903. jna HWUSKZEN
  904. jmp ienv45
  905. HWUSKZEN:
  906. ;;;;;;;; mov cx,74
  907. mov cx,72
  908. jmp ienv100
  909. @@:
  910. jmp ienv90
  911. ienv45:
  912. cmp dx,7840h
  913. jb @f
  914. cmp dx,787Fh
  915. jna HWUSKHAN
  916. cmp dx,7D01h
  917. jb @f
  918. cmp dx,7D7Fh
  919. jna HWUSKHAN
  920. cmp dx,7E01h
  921. jb @f
  922. cmp dx,7E7Fh
  923. ;;;;;;;; ja @f
  924. jna HWUSKHAN
  925. jmp @f
  926. HWUSKHAN:
  927. ;;;;;;;; mov cx,50
  928. mov cx,48
  929. jmp ienv100
  930. @@:
  931. ret
  932. else ;!NEC_98
  933. cmp ah,10h
  934. jnz ienv20
  935. ;
  936. ; Video palette control function. Check for subfunctions that require
  937. ; special actions.
  938. ienv10: cmp al,2 ;update all palette registers?
  939. jnz @F
  940. mov cx,17 ;palette data is 17 bytes long
  941. jmp short ienv70 ;go copy the data
  942. ;
  943. @@: cmp al,9 ;read all palette registers
  944. jz ienv72
  945. ;
  946. cmp al,12h ;update video DAC color registers
  947. jnz @F
  948. mov cx,[bp].pmUserCX ;count of table entries is in caller CX
  949. add cx,cx ;each entry is 3 bytes long
  950. add cx,[bp].pmUserCX
  951. jmp short ienv70 ;go copy the data down
  952. @@: cmp al,17h ;read a block of video DAC registers
  953. jz ienv72
  954. ;
  955. jmp short ienv90
  956. ;
  957. ;
  958. ienv20: cmp ah,11h
  959. jnz ienv30
  960. ;
  961. ; Character generator interface function.
  962. ; NOTE: a number of subfunctions of function 11h need to have munging
  963. ; and data buffering performed. However, function 30h is the only
  964. ; one used by Codeview, so this is the only one currently implemented.
  965. ; For this one, nothing needs to be done on entry, only on exit.
  966. jmp short ienv90
  967. ;
  968. ;
  969. ienv30: cmp ah,1Bh
  970. jnz ienv40
  971. ;
  972. ; Video BIOS functionality/state information.
  973. ; On entry, we need to fix up ES:DI to point to our buffer.
  974. mov [bp].intUserDI,offset DGROUP:rgbXfrBuf0
  975. jmp short ienv90
  976. ;
  977. ;
  978. ienv40:
  979. jmp short ienv90
  980. ;
  981. ; Copy the buffer from the user ES:DX to our transfer buffer and set
  982. ; the value to DX passed to the interrupt routine to point to our buffer.
  983. ienv70: cld
  984. jcxz ienv90
  985. push ds
  986. mov si,[bp].pmUserDX
  987. mov ds,[bp].pmUserES
  988. mov di,offset DGROUP:rgbXfrBuf1
  989. cld
  990. rep movsb
  991. pop ds
  992. ;
  993. ienv72: mov [bp].intUserDX,offset DGROUP:rgbXfrBuf1
  994. jmp short ienv90
  995. ;
  996. ; All done
  997. ienv90:
  998. ret
  999. endif ;!NEC_98
  1000. ; -------------------------------------------------------
  1001. ; IntExitVideo: This routine performs any register
  1002. ; fixups and data copying needed on exit from the
  1003. ; PC BIOS video interrupt (Int 10h).
  1004. ;
  1005. ; Input: register values on stack frame
  1006. ; Output: register values on stack frame
  1007. ; Errors: none
  1008. ; Uses: any registers modified
  1009. ; possibly modifies buffers rgbXfrBuf0 or rgbXfrBuf1
  1010. assume ds:DGROUP,es:DGROUP,ss:NOTHING
  1011. public IntExitVideo
  1012. IntExitVideo:
  1013. ifdef NEC_98
  1014. ;video mode
  1015. cmp ah,0Fh
  1016. jnz iexv10
  1017. jmp iexv80
  1018. iexv10:
  1019. cmp ah,14h
  1020. jnz iexv20
  1021. cmp dh,00h
  1022. jnz iexv11
  1023. mov cx,10
  1024. jmp iexv70
  1025. iexv11:
  1026. cmp dh,80h ;ANK(7*13)
  1027. jnz iexv12
  1028. mov cx,18
  1029. jmp iexv70
  1030. iexv12:
  1031. test fPCH98,0FFh
  1032. jnz @f
  1033. cmp dx,2920h
  1034. jb iexv13
  1035. cmp dx,297dh
  1036. ja iexvhan1
  1037. mov cx,18
  1038. jmp iexv70
  1039. iexvhan1:
  1040. cmp dx,2a20h
  1041. jb iexv13
  1042. cmp dx,2a5fh
  1043. ja iexv13
  1044. mov cx,18
  1045. jmp iexv70
  1046. @@:
  1047. jmp H98_FontRead_N
  1048. iexv13:
  1049. mov cx,34
  1050. jmp iexv70
  1051. iexv20:
  1052. cmp ah,1Fh
  1053. jnz iexv30
  1054. cmp dh,00h
  1055. jnz iexv21
  1056. mov cx,48
  1057. jmp iexv100
  1058. iexv21:
  1059. test fPCH98,0FFh
  1060. jnz @f
  1061. cmp dx,2920h
  1062. jb Hmode_han1
  1063. cmp dx,297dh
  1064. ja Hmode_han1
  1065. mov cx,48
  1066. jmp iexv100
  1067. Hmode_han1:
  1068. cmp dx,2a20h
  1069. jb iexv22
  1070. cmp dx,2a5fh
  1071. ja iexv22
  1072. mov cx,48
  1073. jmp iexv100
  1074. @@:
  1075. jmp H98_FontRead_H
  1076. iexv22:
  1077. mov cx,72
  1078. jmp iexv100
  1079. iexv30:
  1080. cmp ah,1Ah
  1081. jnz iexv40
  1082. jmp iexv80
  1083. iexv40:
  1084. cmp ah,20h
  1085. jnz iexv90
  1086. jmp iexv110
  1087. iexv70:
  1088. cld
  1089. push es
  1090. mov di,[bp].pmUserCX
  1091. mov es,[bp].pmUserBX
  1092. mov si,offset DGROUP:rgbXfrBuf1
  1093. rep movsb
  1094. pop es
  1095. ;
  1096. ; Restore the caller's CX
  1097. iexv80:
  1098. push ax
  1099. mov ax,[bp].pmUserBX ;BX regster restor
  1100. mov [bp].intUserBX,ax
  1101. ;------------------------------------------------------------
  1102. mov ax,[bp].pmUserCX
  1103. mov [bp].intUserCX,ax
  1104. pop ax
  1105. iexv90:
  1106. ret
  1107. iexv100:
  1108. cld
  1109. push es
  1110. mov di,[bp].pmUserBX
  1111. mov es,[bp].pmUserDS
  1112. mov si,offset DGROUP:rgbXfrBuf1
  1113. rep movsb
  1114. pop es
  1115. ;
  1116. ; Restore the caller's CX
  1117. iexv110:
  1118. push ax
  1119. mov ax,[bp].pmUserDS ;BX regster restor
  1120. mov [bp].intUserDS,ax
  1121. ;------------------------------------------------------------
  1122. mov ax,[bp].pmUserBX
  1123. mov [bp].intUserBX,ax
  1124. pop ax
  1125. iexv120:
  1126. ret
  1127. H98_FontRead_N:
  1128. cmp dx,2920h
  1129. jb iexvN15
  1130. cmp dx,297fh
  1131. jna iexvNhan
  1132. cmp dx,2a20h
  1133. jb iexvN15
  1134. cmp dx,2a7fh
  1135. jna iexvNhan
  1136. cmp dx,2b20h
  1137. jb iexvN15
  1138. cmp dx,2b7fh
  1139. jna iexvNhan
  1140. cmp dx,7840h
  1141. jb iexvN15
  1142. cmp dx,787fh
  1143. jna iexvNhan
  1144. cmp dx,7d01h
  1145. jb iexvN15
  1146. cmp dx,7d7fh
  1147. jna iexvNhan
  1148. cmp dx,7e01h
  1149. jb iexvN15
  1150. cmp dx,7e7fh
  1151. ja iexvN15
  1152. iexvNhan:
  1153. mov cx,18 ;16byte+2=18 ; jmp iexv70
  1154. iexvN15:
  1155. mov cx,34 ;32byte+2=34
  1156. jmp iexv70
  1157. H98_FontRead_H:
  1158. cmp dx,2920h
  1159. jb iexvN25
  1160. cmp dx,297fh
  1161. jna HiexvNhan
  1162. cmp dx,2a20h
  1163. jb iexvN25
  1164. cmp dx,2a7fh
  1165. jna HiexvNhan
  1166. cmp dx,2b20h
  1167. jb iexvN25
  1168. cmp dx,2b7fh
  1169. jna HiexvNhan
  1170. cmp dx,7840h
  1171. jb iexvN25
  1172. cmp dx,787fh
  1173. jna HiexvNhan
  1174. cmp dx,7d01h
  1175. jb iexvN25
  1176. cmp dx,7d7fh
  1177. jna HiexvNhan
  1178. cmp dx,7e01h
  1179. jb iexvN25
  1180. cmp dx,7e7fh
  1181. ja iexvN25
  1182. HiexvNhan:
  1183. ;;;;;;;; mov cx,50 ;48byte+2=50
  1184. mov cx,48 ;48byte
  1185. ;;;;;;;; jmp iexv70
  1186. jmp iexv100
  1187. iexvN25:
  1188. ;;;;;;;; mov cx,74 ;72byte+2=74
  1189. mov cx,72 ;72byte
  1190. ;;;;;;;; jmp iexv70
  1191. jmp iexv100
  1192. else ;!NEC_98
  1193. cmp ah,10h
  1194. jnz iexv20
  1195. ;
  1196. ; Palette control function.
  1197. cmp al,9 ;read palette data function
  1198. jnz @F
  1199. mov cx,17
  1200. jmp short iexv70
  1201. ;
  1202. @@: cmp al,17h ;read video DAC registers
  1203. jnz @F
  1204. mov cx,[bp].pmUserCX ;each entry in table is 3 bytes long
  1205. add cx,cx
  1206. add cx,[bp].pmUserCX
  1207. jmp short iexv70
  1208. ;
  1209. @@: jmp short iexv72
  1210. ;
  1211. ;
  1212. iexv20: cmp ah,11h
  1213. jnz iexv30
  1214. ;
  1215. ; Character generator interface function.
  1216. ; NOTE: a number of subfunctions of function 11h need to have munging
  1217. ; and data buffering performed. However, function 30h is the only
  1218. ; one used by Codeview, so this is the only one currently implemented
  1219. cmp al,30h
  1220. jnz @F
  1221. mov ax,[bp].intUserES ;get the paragraph address returned by BIOS
  1222. mov bx,STD_DATA
  1223. call ParaToLDTSelector ;get a selector for that address
  1224. mov [bp].pmUserES,ax ;store the selector so that it will be
  1225. ; returned to the caller
  1226. @@: jmp short iexv90
  1227. ;
  1228. ;
  1229. iexv30: cmp ah,1Bh
  1230. jnz iexv40
  1231. ;
  1232. ; Video BIOS functionality/state information.
  1233. ; On exit, we need to fix up the pointer at the beginning of the
  1234. ; data put in our buffer by the BIOS, and then transfer the buffer up
  1235. ; to the user.
  1236. mov ax,word ptr rgbXfrBuf0[2] ;get segment of pointer to
  1237. ; 'static functionallity table'
  1238. mov bx,STD_DATA
  1239. call ParaToLDTSelector ;convert paragraph to selector
  1240. mov word ptr rgbXfrBuf0[2],ax ;store back into table
  1241. push es
  1242. mov si,offset rgbXfrBuf0 ;pointer to our copy of the table
  1243. mov di,[bp].pmUserDI ;where the user wants it
  1244. mov [bp].intUserDi,di ;restore the DI returned to the user
  1245. mov es,[bp].pmUserES
  1246. mov cx,64 ;the table is 64 bytes long
  1247. cld
  1248. rep movsb ;copy the table to the user's buffer
  1249. pop es
  1250. jmp short iexv90
  1251. ;
  1252. ;
  1253. iexv40:
  1254. jmp short iexv90
  1255. ;
  1256. ; Copy data from our buffer to the caller's buffer pointed to by ES:DX
  1257. iexv70: cld
  1258. push es
  1259. mov di,[bp].pmUserDX
  1260. mov es,[bp].pmUserES
  1261. mov si,offset DGROUP:rgbXfrBuf1
  1262. rep movsb
  1263. pop es
  1264. ;
  1265. ; Restore the caller's DX
  1266. iexv72: mov ax,[bp].pmUserDX
  1267. mov [bp].intUserDX,ax
  1268. ;
  1269. ; All done
  1270. iexv90:
  1271. ret
  1272. endif ;!NEC_98
  1273. ; -------------------------------------------------------
  1274. DXPMCODE ends
  1275. ; -------------------------------------------------------
  1276. subttl BIOS Misc. Interrupt (Int 15h) Service Routine
  1277. page
  1278. ; -------------------------------------------------------
  1279. ; BIOS MISC. INTERRUPT (INT 15h) SERVICE ROUTINE
  1280. ; -------------------------------------------------------
  1281. DXPMCODE segment
  1282. assume cs:DXPMCODE
  1283. ; -------------------------------------------------------
  1284. ; PMIntrMisc -- Entry point into the interrupt processing code
  1285. ; for the BIOS misc functions interrupt (INT 15h).
  1286. ;
  1287. ; Input: normal registers for Bios calls
  1288. ; Output: normal register returns for Bios calls
  1289. ; Errors: normal Bios errors
  1290. ; Uses: as per Bios calls
  1291. assume ds:NOTHING,es:NOTHING,ss:NOTHING
  1292. public PMIntrMisc
  1293. PMIntrMisc:
  1294. ;
  1295. call EnterIntHandler ;build a stack frame and fix up the
  1296. cld ; return address so that the interrupt
  1297. ;service routine will return to us.
  1298. ;
  1299. ; Perform fixups on the entry register values
  1300. call IntEntryMisc
  1301. ;
  1302. ; Execute the interrupt service routine
  1303. SwitchToRealMode
  1304. assume ss:DGROUP
  1305. pop es
  1306. pop ds
  1307. assume ds:NOTHING,es:NOTHING
  1308. popa
  1309. sub sp,8 ; make room for stack frame
  1310. push bp
  1311. mov bp,sp
  1312. push es
  1313. push ax
  1314. xor ax,ax
  1315. mov es,ax
  1316. mov [bp + 8],cs
  1317. mov word ptr [bp + 6],offset pim_10
  1318. mov ax,es:[15h*4]
  1319. mov [bp + 2],ax
  1320. mov ax,es:[15h*4 + 2]
  1321. mov [bp + 4],ax
  1322. pop ax
  1323. pop es
  1324. pop bp
  1325. retf
  1326. pim_10: pushf
  1327. FCLI
  1328. cld
  1329. pusha
  1330. push ds
  1331. push es
  1332. mov bp,sp ;restore stack frame pointer
  1333. SwitchToProtectedMode
  1334. assume ds:DGROUP,es:DGROUP
  1335. ;
  1336. ; Perform fixups on the return register values.
  1337. mov ax,[bp].pmUserAX ;get original function code
  1338. call IntExitMisc
  1339. ;
  1340. ; And return to the original caller.
  1341. call LeaveIntHandler
  1342. riret
  1343. ; -------------------------------------------------------
  1344. ; MISC INTERRUPT SUPPORT ROUTINES
  1345. ; -------------------------------------------------------
  1346. ;
  1347. ; IntEntryMisc -- This function performs data transfer
  1348. ; and register translation on entry to the BIOS Misc.
  1349. ; functions interrupt. (INT 15h).
  1350. ;
  1351. ; Input: AX - BIOS function being performed
  1352. ; Output:
  1353. ; Errors:
  1354. ; Uses: All registers preserved
  1355. assume ds:DGROUP,es:DGROUP,ss:NOTHING
  1356. public IntEntryMisc
  1357. IntEntryMisc:
  1358. ifdef NEC_98
  1359. push cx
  1360. cmp ah,90h ;SYSTEM BIOS BLOCK MOVE
  1361. jnz iemDMA1 ;yes = jmp
  1362. jmp iem70
  1363. iemDMA1:
  1364. cmp ah,0D5h ;DMA BIOS DMA
  1365. jnz iemDMA2 ;yes = jmp
  1366. mov cx,8 ;DMA_CBIOS
  1367. jmp iem70
  1368. iemDMA2:
  1369. cmp ah,0D6h ;DMA BIOS DMA
  1370. jnz iemROM1 ;yes = jmp
  1371. jmp iem80 ;Read JMP
  1372. iemROM1:
  1373. cmp ah,0D8h ;ROM
  1374. jnz iemROM2 ;yes = jmp
  1375. mov cx,4
  1376. jmp iem70
  1377. iemROM2:
  1378. cmp ah,0D9h ;ROM
  1379. jnz iem90 ;yes = jmp
  1380. mov cx,8 ;ROM BIOS
  1381. iem70:
  1382. push ds
  1383. mov si,[bp].pmUserBX ;offset address
  1384. mov ds,[bp].pmUserES ;segment address
  1385. mov di,offset DGROUP:rgbXfrBuf1
  1386. cld
  1387. rep movsb
  1388. pop ds
  1389. iem80:
  1390. push ax
  1391. mov ax,segDXDataPM
  1392. mov [bp].intUserES,ax ;segment address
  1393. pop ax
  1394. mov [bp].intUserBX,offset DGROUP:rgbXfrBuf1
  1395. iem90:
  1396. pop cx
  1397. ret
  1398. else ;!NEC_98
  1399. ; Map requests to set the PS/2 Pointing Device Handler Address
  1400. cmp ax,0C207h ;PS/2 Set Pointing Device Handler adr?
  1401. jnz iem90
  1402. mov ax,[bp].pmUserBX ;User's ES:BX -> handler
  1403. mov word ptr lpfnUserPointingHandler,ax
  1404. mov ax,[bp].pmUserES
  1405. mov word ptr [lpfnUserPointingHandler+2],ax
  1406. mov ax,segDXCodePM ;pass BIOS address of our handler
  1407. mov [bp].intUserES,ax
  1408. mov ax,offset PointDeviceHandler
  1409. mov [bp].intUserBX,ax
  1410. iem90:
  1411. ret
  1412. endif ;!NEC_98
  1413. ; -------------------------------------------------------
  1414. ; IntExitMisc -- This function performs data transfer
  1415. ; and register translation on exit from the BIOS Misc.
  1416. ; Functions interrupt (INT 15h).
  1417. ;
  1418. ; Input: AX - BIOS function being performed
  1419. ; Output:
  1420. ; Errors:
  1421. ; Uses: All registers preserved
  1422. assume ds:DGROUP,es:DGROUP,ss:NOTHING
  1423. public IntExitMisc
  1424. IntExitMisc:
  1425. ifdef NEC_98
  1426. push cx
  1427. cmp ah,90h ;SYSTEM BIOS BLOCK MOVE
  1428. jnz ixmDMA1 ;yes = jmp
  1429. jmp ixm70
  1430. ixmDMA1:
  1431. cmp ah,0D5h ;DMA BIOS
  1432. jnz ixmDMA2 ;yes = jmp
  1433. jmp ixm70
  1434. ixmDMA2:
  1435. cmp ah,0D6h ;DMA BIOS DMA
  1436. jnz ixmROM1 ;yes = jmp
  1437. mov cx,16
  1438. jmp ixm80
  1439. ixmROM1:
  1440. cmp ah,0D8h ; ROM
  1441. jnz ixmROM2 ;yes = jmp
  1442. jmp ixm70
  1443. ixmROM2:
  1444. cmp ah,0D9h ; ROM
  1445. jnz ixm90
  1446. ixm70:
  1447. cld
  1448. push es
  1449. mov di,[bp].pmUserBX
  1450. mov es,[bp].pmUserES
  1451. mov si,offset DGROUP:rgbXfrBuf1
  1452. rep movsb
  1453. pop es
  1454. ;
  1455. ; Restore the caller's ES,BX
  1456. ixm80:
  1457. push ax
  1458. mov ax,[bp].pmUserES
  1459. mov [bp].intUserES,ax
  1460. mov ax,[bp].pmUserBX
  1461. mov [bp].intUserBX,ax
  1462. pop ax
  1463. ixm90:
  1464. pop cx
  1465. ret
  1466. else ;!NEC_98
  1467. push ax
  1468. push bx
  1469. push cx
  1470. push dx
  1471. ;
  1472. ; Check for function 0C0h - Return System Configuration Parameters
  1473. cmp ah,0C0h
  1474. jnz ixmi30
  1475. test [bp].intUserFL,1 ;check if the bios call returned an error
  1476. jnz ixmi90 ;(carry flag set in returned flags)
  1477. ;
  1478. ; The BIOS call succeeded. This means that ES:BX points to a configuration
  1479. ; vector. We need to fix up the segment to be a selector.
  1480. mov dx,[bp].intUserES
  1481. cmp dx,0F000h ;does it point to normal BIOS segment
  1482. jnz ixmi22
  1483. mov ax,SEL_BIOSCODE or STD_RING
  1484. jmp short ixmi24
  1485. ixmi22: call ParaToLinear
  1486. mov cx,0FFFFh
  1487. mov ax,SEL_USERSCR or STD_TBL_RING
  1488. cCall NSetSegmentDscr,<ax,bx,dx,0,cx,STD_DATA>
  1489. ixmi24: mov [bp].pmUserES,ax
  1490. jmp short ixmi90
  1491. ; Chack for function 0C207h - PS/2 Set Pointing Device Handler Address
  1492. ixmi30:
  1493. cmp ax,0C207h
  1494. jne ixmi90
  1495. mov ax,[bp].pmUserBX ;restore user's BX
  1496. mov [bp].intUserBX,ax
  1497. ; All done
  1498. ixmi90:
  1499. pop dx
  1500. pop cx
  1501. pop bx
  1502. pop ax
  1503. ret
  1504. endif ;!NEC_98
  1505. ; -------------------------------------------------------
  1506. DXPMCODE ends
  1507. ; -------------------------------------------------------
  1508. subttl Mouse Function Interrupt (Int 33h) Service Routine
  1509. page
  1510. ; -------------------------------------------------------
  1511. ; MOUSE FUNCTION INTERRUPT (INT 33h) SERVICE ROUTINE
  1512. ; -------------------------------------------------------
  1513. DXPMCODE segment
  1514. assume cs:DXPMCODE
  1515. ; -------------------------------------------------------
  1516. ; PMIntrMouse - Entry point into interrupt reflector code
  1517. ; for mouse driver (int 33h) calls.
  1518. ;
  1519. ; Input: normal registers for mouse calls
  1520. ; Output: normal register returns for mouse calls
  1521. ; Errors: normal mouse errors
  1522. ; Uses: as per mouse calls
  1523. assume ds:NOTHING,es:NOTHING,ss:NOTHING
  1524. public PMIntrMouse
  1525. PMIntrMouse:
  1526. ;
  1527. call EnterIntHandler ;build a stack frame and fix up the
  1528. cld ; return address so that the interrupt
  1529. ;service routine will return to us.
  1530. ;
  1531. ; Perform fixups on the entry register values
  1532. call IntEntryMouse
  1533. ;
  1534. ; Execute the interrupt service routine
  1535. SwitchToRealMode
  1536. assume ss:DGROUP
  1537. pop es
  1538. pop ds
  1539. assume ds:NOTHING,es:NOTHING
  1540. popa
  1541. sub sp,8 ; make room for stack frame
  1542. push bp
  1543. mov bp,sp
  1544. push es
  1545. push ax
  1546. xor ax,ax
  1547. mov es,ax
  1548. mov [bp + 8],cs
  1549. mov word ptr [bp + 6],offset pimo_10
  1550. mov ax,es:[33h*4]
  1551. mov [bp + 2],ax
  1552. mov ax,es:[33h*4 + 2]
  1553. mov [bp + 4],ax
  1554. pop ax
  1555. pop es
  1556. pop bp
  1557. retf
  1558. pimo_10: pushf
  1559. FCLI
  1560. cld
  1561. pusha
  1562. push ds
  1563. push es
  1564. mov bp,sp ;restore stack frame pointer
  1565. SwitchToProtectedMode
  1566. assume ds:DGROUP,es:DGROUP
  1567. ;
  1568. ; Perform fixups on the return register values.
  1569. mov ax,[bp].pmUserAX ;get original function code
  1570. call IntExitMouse
  1571. ;
  1572. ; And return to the original caller.
  1573. call LeaveIntHandler
  1574. riret
  1575. ; -------------------------------------------------------
  1576. ; MOUSE SUPPORT ROUTINES
  1577. ; -------------------------------------------------------
  1578. ; IntEntryMouse -- This function performs data transfer and
  1579. ; register translation on entry to mouse driver functions.
  1580. ; (INT 33h)
  1581. ;
  1582. ; Input: AX - mouse function being performed
  1583. ; Output:
  1584. ; Errors:
  1585. ; Uses: NOTHING
  1586. assume ds:DGROUP,es:DGROUP,ss:NOTHING
  1587. public IntEntryMouse
  1588. IntEntryMouse:
  1589. cld
  1590. push ax
  1591. push cx
  1592. push si
  1593. push di
  1594. ;
  1595. cmp al,9 ;Set graphics cursor block?
  1596. jnz ment10
  1597. ;
  1598. ; The user is setting a graphics cursor. We need to copy the masks
  1599. ; down to low memory so that the mouse driver can get at them and then
  1600. ; fix up the pointer in DX.
  1601. mov cx,32
  1602. jmp short ment92
  1603. ;
  1604. ; Mouse interrupt handler establishment
  1605. ment10: cmp al,12 ;Set user defined interrupt subroutine ?
  1606. jnz ment20
  1607. ;
  1608. ; This command has the effect of causing a call to the address es:ds
  1609. ; Whenever an event of one of the types specified by the mask in cx.
  1610. ; The address es:dx must be saved in lpfnUserMouseHandler and the
  1611. ; real mode address of MouseInterruptHandler substituted.
  1612. mov ax,[bp].pmUserDX ; Load users handler offset
  1613. mov word ptr lpfnUserMouseHandler,ax ; Store for future use
  1614. mov ax,[bp].pmUserES ; Load users handler segment value
  1615. mov word ptr lpfnUserMouseHandler + 2,ax ; Store for future use
  1616. mov ax,segDXCodePM ; Load real mode code segment value
  1617. mov [bp].intUserES,ax ; Store in real mode es register image
  1618. mov ax,offset MouseInterruptHandler ; Load handler offset
  1619. mov [bp].intUserDX,ax ; Store in real mode dx register image
  1620. jmp short ment99 ;Return
  1621. ;
  1622. ment20: cmp al,20
  1623. jc ment99
  1624. jnz ment30
  1625. ;
  1626. ; This is the swap interrupt subroutine function. Not currently implemented
  1627. jmp short ment99
  1628. ;
  1629. ment30: cmp al,22 ;Save mouse driver state?
  1630. jnz ment40
  1631. ;
  1632. ; This is the save mouse driver state function. We need to pass a pointer
  1633. ; to the transer buffer down to the mouse driver.
  1634. mov ax,npXfrBuf1
  1635. mov [bp].intUserDX,ax
  1636. jmp short ment99
  1637. ment40: cmp al,23 ;Restore mouse driver state?
  1638. jnz ment99
  1639. ;
  1640. ; This is the restore mouse driver state function. We need to copy the
  1641. ; mouse state buffer from the pm user location to the transfer buffer,
  1642. ; and then pass the pointer to the transfer buffer on to the mouse driver.
  1643. mov cx,cbMouseState
  1644. jcxz ment99
  1645. ;
  1646. ; Transfer the data pointed to by the user ES:DX to the scratch buffer, and
  1647. ; fix up the pointer that is passed on to the mouse driver.
  1648. ment92: mov si,[bp].pmUserDX
  1649. mov di,npXfrBuf1
  1650. mov [bp].intUserDX,di
  1651. push ds
  1652. mov ds,[bp].pmUserES
  1653. cld
  1654. rep movs word ptr [di],word ptr [si]
  1655. pop ds
  1656. ;
  1657. ment99: pop di
  1658. pop si
  1659. pop cx
  1660. pop ax
  1661. ret
  1662. ; -------------------------------------------------------
  1663. ; IntExitMouse -- This function performs data transfer and
  1664. ; register translation on exit from mouse driver functions.
  1665. ; (INT 33h)
  1666. ;
  1667. ; Input: AX - mouse function being performed
  1668. ; Output:
  1669. ; Errors:
  1670. ; Uses:
  1671. assume ds:DGROUP,es:DGROUP,ss:NOTHING
  1672. public IntExitMouse
  1673. IntExitMouse:
  1674. cld
  1675. cmp al,21 ;get state buffer size?
  1676. jnz mxit20
  1677. ;
  1678. ; We need to remember the state buffer size, so that later we will know
  1679. ; how many bytes to transfer when we do the save/restore state fucntions.
  1680. mov ax,[bp].intUserBX
  1681. mov cbMouseState,ax
  1682. return
  1683. ;
  1684. mxit20: cmp al,22 ;Save mouse driver state?
  1685. jnz mxit30
  1686. ;
  1687. ; We need to restore the original values of ES:DX and transfer the mouse
  1688. ; state data from the real mode buffer to the user's protected mode buffer.
  1689. mov cx,cbMouseState
  1690. jcxz mxit28
  1691. push es
  1692. mov si,npXfrBuf1
  1693. mov di,[bp].pmUserDX
  1694. mov [bp].intUserDX,di
  1695. mov es,[bp].pmUserES
  1696. rep movs byte ptr [di],byte ptr [si]
  1697. pop es
  1698. mxit28: return
  1699. ;
  1700. mxit30: cmp al,23 ;Restore mouse driver state?
  1701. jnz mxit99
  1702. mov ax,[bp].pmUserDX
  1703. mov [bp].intUserDX,ax
  1704. ;
  1705. mxit99: ret
  1706. ; -------------------------------------------------------
  1707. DXPMCODE ends
  1708. ; -------------------------------------------------------
  1709. subttl PM Interrupt Support Routines
  1710. page
  1711. ; -------------------------------------------------------
  1712. ; PM INTERRUPT SUPPORT ROUTINES
  1713. ; -------------------------------------------------------
  1714. DXPMCODE segment
  1715. assume cs:DXPMCODE
  1716. ; -------------------------------------------------------
  1717. ; EnterIntHandler -- This routine will allocate a stack
  1718. ; frame on the interrupt reflector stack and make
  1719. ; a copy of the registers on the allocated stack.
  1720. ;
  1721. ; Note: This routine expects the current stack to contain a near
  1722. ; return address and a normal [IP] [CS] [FL] interrupt stack
  1723. ; frame. Don't have anything else on the stack before calling
  1724. ; this routine!
  1725. ;
  1726. ; Note: This routine disables interrupts, and leaves them disabled.
  1727. ; Most callers already have them disabled, so it doesn't
  1728. ; really make a difference, except that this routine
  1729. ; requires that they be disabled.
  1730. ;
  1731. ; Input: none
  1732. ; Output: stack frame set up
  1733. ; Errors: none
  1734. ; Uses: all registers preserved
  1735. assume ds:NOTHING,es:NOTHING,ss:NOTHING
  1736. public EnterIntHandler
  1737. EnterIntHandler proc near
  1738. FCLI ;we really want int's disabled (and
  1739. ; XMScontrol doesn't do that)
  1740. push ds
  1741. mov ds,selDgroupPM ;save user's DS and address our DGROUP
  1742. assume ds:DGROUP
  1743. pop regUserDS
  1744. push bp
  1745. mov bp,sp ;bp -> [BP] [IP] [IP] [CS] [FL]
  1746. push word ptr [bp+8]
  1747. pop regUserFL ;user's flags before doing INT
  1748. pop bp
  1749. pop pfnReturnAddr ;near return to our immediate caller
  1750. mov regUserSS,ss ;save caller's stack address
  1751. mov regUserSP,sp
  1752. ASSERT_REFLSTK_OK
  1753. mov ss,selDgroupPM ;switch to interrupt reflector stack
  1754. mov sp,pbReflStack
  1755. sub pbReflStack,CB_STKFRAME ;adjust pointer to next stack frame
  1756. FIX_STACK
  1757. ; Build the stack frame. The stack frame contains the following:
  1758. ; dword & word parameter locations
  1759. ; original caller's stack address
  1760. ; caller's original flags and general registers (in pusha form)
  1761. ; caller's original segment registers (DS & ES)
  1762. ; flags and general registers to be passed to interrupt routine
  1763. ; (initially the same as caller's original values)
  1764. ; segment registers (DS & ES) to be passed to interrupt routine
  1765. ; (initially set to the Dos Extender data segment address)
  1766. ;
  1767. ; The parameter words and then the caller's original register values go on top.
  1768. sub sp,8 ;space for a dd & 2 dw's
  1769. push regUserSP
  1770. push regUserSS
  1771. push regUserFL
  1772. pusha
  1773. push regUserDS
  1774. push es
  1775. ; Now, put all of the general registers, and values for the segment
  1776. ; registers to be passed to the interrupt service routine. We pass
  1777. ; the Dos Extender data segment address to the interrupt routine.
  1778. push regUserFL
  1779. pusha
  1780. push segDXDataPM
  1781. push segDXDataPM
  1782. ; And we are done.
  1783. mov bp,sp ;set up frame pointer
  1784. mov es,selDgroupPM
  1785. jmp pfnReturnAddr ;return to the caller.
  1786. EnterIntHandler endp
  1787. ; -------------------------------------------------------
  1788. ; LeaveIntHandler -- This routine will restore the user registers,
  1789. ; release the stack frame, and restore the original user's stack
  1790. ; for exit from an interrupt reflector routine.
  1791. ;
  1792. ; Note: Interrupts must be off when this routine is called.
  1793. ;
  1794. ; Input: none
  1795. ; Output: none
  1796. ; Errors: none
  1797. ; Uses: All registers modified
  1798. assume ds:DGROUP,es:NOTHING,ss:NOTHING
  1799. public LeaveIntHandler
  1800. LeaveIntHandler proc near
  1801. FCLI
  1802. pop pfnReturnAddr
  1803. ; The copy of the register values returned from the interrupt routine
  1804. ; (and then possibly modified by the exit handler for the particular
  1805. ; interrupt) are what gets returned to the caller. We discard the original
  1806. ; register values saved on entry. (They were there so that the exit
  1807. ; routine could refer to them if necessary)
  1808. add sp,4 ;skip over interrupt service routine's
  1809. ; segment register values
  1810. popa ;restore general register values
  1811. pop regUserFL ;flags returned by interrupt routine
  1812. pop es ;get segment registers from pmUserES
  1813. pop regUserDS ; and pmUserDS
  1814. add sp,18 ;skip over the original user registers
  1815. ; and flags
  1816. pop regUserSS ;original interrupted routine's stack
  1817. pop regUserSP
  1818. mov regUserAX,ax
  1819. ; Switch back to the original user's stack.
  1820. ASSERT_REFLSTK_OK
  1821. ASSERT_CLI
  1822. CHECK_STACK
  1823. mov ss,regUserSS
  1824. mov sp,regUserSP
  1825. add pbReflStack,CB_STKFRAME
  1826. ASSERT_REFLSTK_OK
  1827. ; We need to replace the image of the flags in the original int return
  1828. ; address on the user's stack with the new flags returned from the interrupt
  1829. ; service routine.
  1830. push bp
  1831. mov bp,sp ;stack -> BP IP CS FL
  1832. mov ax,regUserFL ;flags returned by interrupt service routine
  1833. and ax,0BFFFh ;clear the nested task flag
  1834. and [bp+6],0300h ;clear all but the interrupt and trace flags
  1835. ; in the caller's original flags
  1836. or [bp+6],ax ;combine in the flags returned by the
  1837. ; interrupt service routine. This will cause
  1838. ; us to return to the original routine with
  1839. ; interrupts on if they were on when the
  1840. ; interrupt occured, or if the ISR returned
  1841. ; with them on.
  1842. pop bp
  1843. ; And now, return to the caller.
  1844. push pfnReturnAddr
  1845. mov ax,regUserAX
  1846. mov ds,regUserDS
  1847. assume ds:NOTHING
  1848. ret
  1849. LeaveIntHandler endp
  1850. ; -------------------------------------------------------
  1851. DXPMCODE ends
  1852. ; -------------------------------------------------------
  1853. subttl Mouse Interrupt Callback Function Handler
  1854. page
  1855. ; -------------------------------------------------------
  1856. ; MOUSE INTERRUPT CALLBACK FUNCTION HANDLER
  1857. ; -------------------------------------------------------
  1858. DXCODE segment
  1859. assume cs:DXCODE
  1860. ; -------------------------------------------------------
  1861. ; MouseInterruptHandler -- This routine is the entry point for
  1862. ; user requested mouse event interrupts. It switches the
  1863. ; processor to protected mode and transfers control to the
  1864. ; user protected mode mouse handling routine. When that
  1865. ; completes, it switches back to real mode and returns control
  1866. ; to the mouse driver.
  1867. ; Entry to this routine will have been requested by an
  1868. ; INT 33H code 12 with the real address of this routine
  1869. ; substituted for the users entry point.
  1870. ; The address of the user specified mouse handler as specified
  1871. ; in the original INT 33H is stored in the variable
  1872. ; lpfnUserMouseHandler.
  1873. ;
  1874. ; Input: none
  1875. ; Output: none
  1876. ; Errors: none
  1877. ; Uses: The segment registers are explicitly preserved by
  1878. ; this routine. Other registers are as preserved or
  1879. ; modified by the users mouse handler.
  1880. assume ds:NOTHING,es:NOTHING,ss:NOTHING
  1881. public MouseInterruptHandler
  1882. MouseInterruptHandler proc far
  1883. ;
  1884. ; On entry, the stack layout is:
  1885. ; [2] CS - System mouse handler code segment
  1886. ; [0] IP - System mouse handler return offset
  1887. ;
  1888. push es
  1889. push ds
  1890. pushf
  1891. FCLI
  1892. cld
  1893. mov ds,selDgroup
  1894. assume ds:DGROUP
  1895. pop regUserFL
  1896. ;
  1897. ; Allocate a new stack frame, and then switch to the local stack
  1898. ; frame.
  1899. mov regUserSP,sp ;save entry stack pointer so we can restore it
  1900. mov regUSerSS,ss ;save segment too
  1901. mov ss,selDgroup ;switch to our own stack frame
  1902. ASSERT_REFLSTK_OK
  1903. mov sp,pbReflStack
  1904. sub pbReflStack,CB_STKFRAME ;adjust pointer to next stack frame
  1905. FIX_STACK
  1906. ;
  1907. ; We are now running on our own stack, so we can switch into protected mode.
  1908. push ax ;preserve caller's AX
  1909. SwitchToProtectedMode
  1910. pop ax
  1911. ;
  1912. ; Build a far return frame on the stack so that the user's
  1913. ; routine will return to us when it is finished.
  1914. push regUserSS ; save system mouse handler stack address
  1915. push regUserSP ; so we can restore it later
  1916. push ds
  1917. push cs
  1918. push offset mih50
  1919. ;
  1920. ; Build an IRET frame on the stack to use to transfer control to the
  1921. ; user's protected mode routine
  1922. push regUserFL
  1923. push word ptr lpfnUserMouseHandler+2 ;push segment of user routine
  1924. push word ptr lpfnUserMouseHandler ;push offset of user routine
  1925. ;
  1926. ; At this point the interrupt reflector stack looks like this:
  1927. ;
  1928. ; [14] stack segment of original stack
  1929. ; [12] stack pointer of original stack
  1930. ; [10] real mode dos extender data segment
  1931. ; [8] segment of return address back to here
  1932. ; [6] offset of return address back here
  1933. ; [4] Users flags
  1934. ; [2] segment of user routine
  1935. ; [0] offset of user routine
  1936. ;
  1937. ; Execute the users mouse handler
  1938. iret
  1939. ;
  1940. ; The users handler will return here after it is finsished.
  1941. mih50: FCLI
  1942. cld
  1943. pop ds
  1944. pop regUserSP
  1945. pop regUserSS
  1946. ;
  1947. ; Switch back to real mode.
  1948. push ax ;preserve AX
  1949. SwitchToRealMode
  1950. pop ax
  1951. CHECK_STACK
  1952. ;
  1953. ; Switch back to the original stack.
  1954. mov ss,regUserSS
  1955. mov sp,regUserSP
  1956. ASSERT_REFLSTK_OK
  1957. ;
  1958. ; Deallocate the stack frame that we are using.
  1959. add pbReflStack,CB_STKFRAME
  1960. ASSERT_REFLSTK_OK
  1961. ;
  1962. ; And return to the original interrupted program.
  1963. pop ds
  1964. pop es
  1965. ret
  1966. MouseInterruptHandler endp
  1967. ; -------------------------------------------------------
  1968. DXCODE ends
  1969. ; -------------------------------------------------------
  1970. subttl PS/2 Pointing Device Handler
  1971. page
  1972. ; -------------------------------------------------------
  1973. ; PS/2 POINTING DEVICE HANDLER
  1974. ; -------------------------------------------------------
  1975. DXCODE segment
  1976. assume cs:DXCODE
  1977. ifndef NEC_98
  1978. ; -------------------------------------------------------
  1979. ; PointDeviceHandler -- This routine is the entry point for
  1980. ; the PS/2 Pointing Device Handler. It switches the
  1981. ; processor to protected mode and transfers control to the
  1982. ; user pointing device handler. When that completes,
  1983. ; it switches back to real mode and returns control to
  1984. ; the PS/2 BIOS.
  1985. ;
  1986. ; Note: The BIOS calls us with interrutps enabled!
  1987. ; Input: none
  1988. ; Output: none
  1989. ; Errors: none
  1990. assume ds:NOTHING,es:NOTHING,ss:NOTHING
  1991. public PointDeviceHandler
  1992. PointDeviceHandler proc far
  1993. ; On entry, the stack layout is:
  1994. ;
  1995. ; [10] status
  1996. ; [8] X coordinate
  1997. ; [6] Y coordinate
  1998. ; [4] Z coordinate
  1999. ; [2] CS - PS/2 BIOS code segment
  2000. ; [0] IP - PS/2 BIOS return offset
  2001. cld
  2002. push es ;save PS/2 BIOS ds/es on it's stack
  2003. push ds
  2004. mov ds,selDgroup ;addressability to DOSX DGROUP
  2005. push ds
  2006. pop es
  2007. assume ds:DGROUP,es:DGROUP
  2008. FCLI ;protect global regUserXX vars
  2009. ; Allocate a new stack frame, and then switch to the local stack
  2010. ; frame.
  2011. mov regUserSP,sp ;save entry stack pointer so we can restore it
  2012. mov regUSerSS,ss ;save segment too
  2013. ASSERT_REFLSTK_OK
  2014. mov ss,selDgroup ;switch to our own stack frame
  2015. mov sp,pbReflStack
  2016. sub pbReflStack,CB_STKFRAME ;adjust pointer to next stack frame
  2017. FIX_STACK
  2018. push regUserSS ;save PS/2 BIOS stack address
  2019. push regUserSP ; so we can restore it later
  2020. push SEL_DXDATA or STD_RING ;DOSX DS to be poped in PM
  2021. sub sp,4*2 ;temp save the general regs further down the
  2022. pusha ; stack, they'll get poped in a little while
  2023. ; Copy PS/2 pointing device stack info to our (soon to be) protected mode stack
  2024. mov si,regUserSP ;PS/2 stack pointer
  2025. mov ds,regUserSS ;PS/2 stack segment
  2026. assume ds:NOTHING
  2027. FSTI ;no more references to global regUserXX vars
  2028. add si,4*2 ;skip over es,ds,cs,ip
  2029. mov di,sp ;loc for pointing device
  2030. add di,8*2 ; data on our stack
  2031. mov cx,4
  2032. cld
  2033. rep movsw
  2034. push es ;restore ds = DGROUP
  2035. pop ds
  2036. assume ds:DGROUP
  2037. ; We are now running on our own stack, so we can switch into protected mode.
  2038. SwitchToProtectedMode ;disables interrupts again
  2039. FSTI ; but we don't want them disabled
  2040. popa ;restore general registers
  2041. ; At this point the stack looks like this:
  2042. ;
  2043. ; [12] stack segment of original stack
  2044. ; [10] stack pointer of original stack
  2045. ; [8] protect mode dos extender data segment
  2046. ; [6] status
  2047. ; [4] X coordinate
  2048. ; [2] Y coordinate
  2049. ; [0] Z coordinate
  2050. ; Execute the user's pointing device handler
  2051. call [lpfnUserPointingHandler]
  2052. ; The users handler will return here after it is finsished.
  2053. pdh50:
  2054. cld
  2055. add sp,4*2 ;discard pointing device info
  2056. pop ds
  2057. FCLI ;protect global regUserXX vars
  2058. pop regUserSP
  2059. pop regUserSS
  2060. ; Switch back to real mode.
  2061. push ax ;preserve AX
  2062. SwitchToRealMode
  2063. pop ax
  2064. ; Switch back to the original stack.
  2065. CHECK_STACK
  2066. mov ss,regUserSS
  2067. mov sp,regUserSP
  2068. ; Deallocate the stack frame that we are using.
  2069. ASSERT_REFLSTK_OK
  2070. add pbReflStack,CB_STKFRAME
  2071. ASSERT_REFLSTK_OK
  2072. ; And return to the PS/2 BIOS
  2073. FSTI ;we came in with ints enabled
  2074. pop ds
  2075. pop es
  2076. ret
  2077. PointDeviceHandler endp
  2078. ; -------------------------------------------------------
  2079. endif ;!NEC_98
  2080. ;
  2081. ; -------------------------------------------------------
  2082. subttl Utility Function Definitions
  2083. page
  2084. ; -------------------------------------------------------
  2085. ; UTILITY FUNCTION DEFINITIONS
  2086. ; -------------------------------------------------------
  2087. ;
  2088. ; SaveRMIntrVectors -- This routine copies the current
  2089. ; real mode interrupt vector table to the shadow
  2090. ; vector table used by the interrupt reflector.
  2091. ;
  2092. ; Input: none
  2093. ; Output: none
  2094. ; Errors: none
  2095. ; Uses; all registers preserved
  2096. ;
  2097. ; NOTE: This routine can only be called in REAL MODE.
  2098. assume ds:DGROUP,es:NOTHING,ss:NOTHING
  2099. public SaveRMIntrVectors
  2100. SaveRMIntrVectors:
  2101. push cx
  2102. push si
  2103. push di
  2104. push ds
  2105. push es
  2106. ;
  2107. cld
  2108. push ds
  2109. pop es
  2110. xor cx,cx
  2111. mov si,cx
  2112. mov ds,cx
  2113. mov di,offset DGROUP:rglpfnRmISR
  2114. mov cx,2*256
  2115. rep movs word ptr [di],word ptr [si]
  2116. ;
  2117. pop es
  2118. pop ds
  2119. pop di
  2120. pop si
  2121. pop cx
  2122. ret
  2123. ; -------------------------------------------------------
  2124. ; RestoreRMIntrVectors -- This routine copies the
  2125. ; interrupt vectors from the real mode interrupt
  2126. ; vector shadow table back down to the real interrupt
  2127. ; vectors.
  2128. ;
  2129. ; Input: none
  2130. ; Output: none
  2131. ; Errors: none
  2132. ; Uses; all registers preserved
  2133. ;
  2134. ; NOTE: This routine can only be called in REAL MODE.
  2135. assume ds:DGROUP,es:NOTHING,ss:NOTHING
  2136. public RestoreRMIntrVectors
  2137. RestoreRMIntrVectors:
  2138. push cx
  2139. push si
  2140. push di
  2141. push ds
  2142. push es
  2143. ;
  2144. FCLI
  2145. cld
  2146. xor cx,cx
  2147. mov di,cx
  2148. mov es,cx
  2149. mov si,offset DGROUP:rglpfnRmISR
  2150. mov cx,2*256
  2151. rep movs word ptr [di],word ptr [si]
  2152. FSTI
  2153. ;
  2154. pop es
  2155. pop ds
  2156. pop di
  2157. pop si
  2158. pop cx
  2159. ret
  2160. ; -------------------------------------------------------
  2161. DXCODE ends
  2162. ifdef NEC_98
  2163. ;
  2164. ; -------------------------------------------------------
  2165. subttl INT D2h SOUND BIOS HANDRER
  2166. page
  2167. ; -------------------------------------------------------
  2168. ; PMIntrSound
  2169. ;--------------------------------------------------------
  2170. DXPMCODE segment
  2171. assume cs:DXPMCODE
  2172. assume ds:NOTHING,es:NOTHING,ss:NOTHING
  2173. public PMIntrSound
  2174. PMIntrSound:
  2175. call EnterIntHandler ;build a stack frame and fix up the
  2176. cld ; return address so that the interrupt
  2177. ;service routine will return to us.
  2178. ;
  2179. ; Perform fixups on the entry register values
  2180. call IntEntrySD
  2181. ;
  2182. ; Execute the interrupt service routine
  2183. SwitchToRealMode
  2184. assume ss:DGROUP
  2185. pop es
  2186. pop ds
  2187. assume ds:NOTHING,es:NOTHING
  2188. popa
  2189. call rglpfnRmISR[4*0D2h] ;execute the real mode interrupt routine
  2190. pushf
  2191. cli
  2192. cld
  2193. pusha
  2194. push ds
  2195. push es
  2196. mov bp,sp ;restore stack frame pointer
  2197. SwitchToProtectedMode
  2198. assume ds:DGROUP,es:DGROUP
  2199. ;
  2200. ; Perform fixups on the return register values.
  2201. mov ax,[bp].pmUserAX ;get original function code
  2202. call IntExitSD
  2203. ;
  2204. ; And return to the original caller.
  2205. call LeaveIntHandler
  2206. iret
  2207. ;--------------------------------------------------------
  2208. ; IntEntrySD
  2209. ;--------------------------------------------------------
  2210. assume ds:DGROUP,es:DGROUP,ss:NOTHING
  2211. public IntEntrySD
  2212. IntEntrySD:
  2213. cmp ah,0 ;BIOS(INITIALIZE)
  2214. jnz ienSD10
  2215. mov bx,0 ;BIOS
  2216. mov si,bx
  2217. mov cx,2FFh ;(256) (512)
  2218. jmp ienSD50
  2219. ienSD10:
  2220. cmp ah,1 ;(PLAY)
  2221. jnz ienSD20
  2222. mov si,[bp].pmUserBX
  2223. mov cx,28
  2224. jmp ienSD50
  2225. ienSD20:
  2226. cmp ah,16h ;(SET PARA BLOCK)
  2227. jnz ienSD90
  2228. mov si,[bp].pmUserBX
  2229. cmp dl,0 ;00=WORD/01=BYTE?
  2230. jnz ienSD21 ;not 0 = JMP
  2231. mov cx,100 ;100
  2232. jmp ienSD50
  2233. ienSD21:
  2234. mov cx,51 ;51
  2235. ienSD50:
  2236. push ds
  2237. ;;;; mov si,[bp].pmUserBX ;
  2238. mov ds,[bp].pmUserES ;
  2239. mov di,offset DGROUP:rgbXfrBuf1
  2240. rep movsb
  2241. pop ds
  2242. push ax
  2243. mov ax,segDXDataPM
  2244. mov [bp].intUserES,ax ;segment address
  2245. pop ax
  2246. ;------------------------------------------------------------
  2247. mov [bp].intUserBX,offset DGROUP:rgbXfrBuf1
  2248. ienSD90:
  2249. ret
  2250. ;--------------------------------------------------------
  2251. ; IntExitSD
  2252. ;--------------------------------------------------------
  2253. assume ds:DGROUP,es:DGROUP,ss:NOTHING
  2254. public IntExitSD
  2255. IntExitSD:
  2256. cmp ah,0 ;BIOS (INITIALIZE)
  2257. jnz iexSD10
  2258. jmp iexSD50
  2259. iexSD10:
  2260. cmp ah,1 ;(PLAY)
  2261. jnz iexSD20
  2262. jmp iexSD50
  2263. iexSD20:
  2264. cmp ah,16h ;(SET PARA BLOCK)
  2265. jnz iexSD90
  2266. iexSD50:
  2267. push ax
  2268. mov ax,[bp].pmUserES
  2269. mov [bp].intUserES,ax
  2270. ;------------------------------------------------------------
  2271. mov ax,[bp].pmUserBX
  2272. mov [bp].intUserBX,ax
  2273. pop ax
  2274. iexSD90:
  2275. ret
  2276. DXPMCODE ends
  2277. ; -------------------------------------------------------
  2278. subttl INT 1Ah PRINTER BIOS HANDRER
  2279. page
  2280. ; 30h( ) 2K
  2281. ; -------------------------------------------------------
  2282. ; PMIntrPrinter
  2283. ;--------------------------------------------------------
  2284. DXPMCODE segment
  2285. assume cs:DXPMCODE
  2286. assume ds:NOTHING,es:NOTHING,ss:NOTHING
  2287. public PMIntrPrinter
  2288. PMIntrPrinter:
  2289. call EnterIntHandler ;build a stack frame and fix up the
  2290. cld ; return address so that the interrupt
  2291. ;service routine will return to us.
  2292. ;
  2293. ; Perform fixups on the entry register values
  2294. call IntEntryPR
  2295. ;
  2296. ; Execute the interrupt service routine
  2297. SwitchToRealMode
  2298. assume ss:DGROUP
  2299. pop es
  2300. pop ds
  2301. assume ds:NOTHING,es:NOTHING
  2302. popa
  2303. call rglpfnRmISR[4*1Ah] ;execute the real mode interrupt routine
  2304. pushf
  2305. cli
  2306. cld
  2307. pusha
  2308. push ds
  2309. push es
  2310. mov bp,sp ;restore stack frame pointer
  2311. SwitchToProtectedMode
  2312. assume ds:DGROUP,es:DGROUP
  2313. ;
  2314. ; Perform fixups on the return register values.
  2315. mov ax,[bp].pmUserAX ;get original function code
  2316. call IntExitPR
  2317. ;
  2318. ; And return to the original caller.
  2319. call LeaveIntHandler
  2320. iret
  2321. ;--------------------------------------------------------
  2322. ; IntEntryPR
  2323. ;--------------------------------------------------------
  2324. assume ds:DGROUP,es:DGROUP,ss:NOTHING
  2325. public IntEntryPR
  2326. IntEntryPR:
  2327. cmp ah,30h ;
  2328. jnz ienPR20 ;90/08/24
  2329. mov cx,[bp].pmUserCX ;
  2330. cmp cx,2048 ;2K
  2331. jbe ienPR10 ;NO = jmp
  2332. mov cx,2048
  2333. mov [bp].intUserCX,cx
  2334. ienPR10:
  2335. push ds
  2336. mov si,[bp].pmUserBX ;offset address
  2337. mov ds,[bp].pmUserES ;segment address
  2338. mov di,offset DGROUP:rgbXfrBuf1
  2339. cld
  2340. rep movsb
  2341. pop ds
  2342. push ax
  2343. mov ax,segDXDataPM
  2344. mov [bp].intUserES,ax ;segment address
  2345. pop ax
  2346. ;------------------------------------------------------------
  2347. mov [bp].intUserBX,offset DGROUP:rgbXfrBuf1
  2348. ienPR20:
  2349. ret
  2350. ;--------------------------------------------------------
  2351. ; IntExitPR
  2352. ;--------------------------------------------------------
  2353. assume ds:DGROUP,es:DGROUP,ss:NOTHING
  2354. public IntExitPR
  2355. IntExitPR:
  2356. cmp ah,30h
  2357. jnz iexPR20
  2358. mov cx,[bp].pmUserCX
  2359. cmp cx,2048
  2360. ja iexPR10 ;YES = jmp
  2361. push ax
  2362. mov ax,[bp].pmUserES
  2363. mov [bp].intUserES,ax
  2364. ;------------------------------------------------------------
  2365. mov ax,[bp].pmUserBX ;offset address
  2366. mov [bp].intUserBX,ax
  2367. pop ax
  2368. ret
  2369. iexPR10:
  2370. push ax
  2371. mov ax,[bp].pmUserES
  2372. mov [bp].intUserES,ax
  2373. ;------------------------------------------------------------
  2374. mov cx,2048
  2375. sub [bp].pmUserCX,cx
  2376. mov ax,[bp].pmUserCX
  2377. mov [bp].intUserCX,ax
  2378. pop ax
  2379. push bx
  2380. add [bp].pmUserBX,cx
  2381. mov bx,[bp].pmUserBX
  2382. mov [bp].intUserBX,bx
  2383. pop bx
  2384. iexPR20:
  2385. ret
  2386. ;////////////////////////////////////////////////////////////
  2387. if 0
  2388. ;////////////////////////////////////////////////////////////
  2389. IntEntryPR:
  2390. cmp ah,30h
  2391. jnz ienPR10
  2392. mov cx,[bp].pmUserCX
  2393. cmp cx,2048
  2394. ja ienPR10 ;YES = jmp
  2395. push ds
  2396. mov si,[bp].pmUserBX ;offset address
  2397. mov ds,[bp].pmUserES ;segment address
  2398. mov di,offset DGROUP:rgbXfrBuf1
  2399. cld
  2400. rep movsb
  2401. pop ds
  2402. push ax
  2403. mov ax,segDXDataPM
  2404. mov [bp].intUserES,ax ;segment address
  2405. pop ax
  2406. ;------------------------------------------------------------
  2407. mov [bp].intUserBX,offset DGROUP:rgbXfrBuf1
  2408. ret
  2409. ienPR10:
  2410. push ds
  2411. mov si,[bp].pmUserBX ;offset address
  2412. mov ds,[bp].pmUserES ;segment address
  2413. mov di,offset DGROUP:rgbXfrBuf1
  2414. cld
  2415. rep movsb
  2416. pop ds
  2417. push ax
  2418. mov ax,segDXDataPM
  2419. mov [bp].intUserES,ax ;segment address
  2420. pop ax
  2421. ;------------------------------------------------------------
  2422. push bx
  2423. mov bx,offset DGROUP:rgbXfrBuf1 ;
  2424. add bx,cx ;DGROUP:rgbXfrBuf1
  2425. mov [bp].intUserBX,bx ;
  2426. pop bx
  2427. ret
  2428. ; push ds
  2429. ; mov [bp].intUserES,ds ;segment address
  2430. ; pop ds
  2431. ;;------------------------------------------------------------
  2432. ; mov bx,offset DGROUP:rgbXfrBuf1 ;
  2433. ; add bx,cx ;
  2434. ; mov [bp].intUserBX,bx ;
  2435. ; ret
  2436. ;
  2437. ;--------------------------------------------------------
  2438. ; IntExitPR
  2439. ;--------------------------------------------------------
  2440. assume ds:DGROUP,es:DGROUP,ss:NOTHING
  2441. public IntExitPR
  2442. IntExitPR:
  2443. cmp ah,30h
  2444. jnz iexPR10
  2445. mov ax,[bp].pmUserES
  2446. mov [bp].intUserES,ax
  2447. ;------------------------------------------------------------
  2448. mov ax,[bp].pmUserBX ;
  2449. mov [bp].intUserBX,ax
  2450. iexPR10:
  2451. ret
  2452. ;////////////////////////////////////////////////////////////
  2453. endif
  2454. ;////////////////////////////////////////////////////////////
  2455. DXPMCODE ends
  2456. ; -------------------------------------------------------
  2457. subttl INT 1Ch CALENDER/TIMER HANDRER
  2458. page
  2459. ; -------------------------------------------------------
  2460. ; PMIntrCalTi
  2461. ;--------------------------------------------------------
  2462. DXPMCODE segment
  2463. assume cs:DXPMCODE
  2464. assume ds:NOTHING,es:NOTHING,ss:NOTHING
  2465. public PMIntrCalTi
  2466. PMIntrCalTi:
  2467. call EnterIntHandler ;build a stack frame and fix up the
  2468. cld ; return address so that the interrupt
  2469. ;service routine will return to us.
  2470. ;
  2471. ; Perform fixups on the entry register values
  2472. call IntEntryCT
  2473. ;
  2474. ; Execute the interrupt service routine
  2475. SwitchToRealMode
  2476. assume ss:DGROUP
  2477. pop es
  2478. pop ds
  2479. assume ds:NOTHING,es:NOTHING
  2480. popa
  2481. call rglpfnRmISR[4*1Ch] ;execute the real mode interrupt routine
  2482. pushf
  2483. cli
  2484. cld
  2485. pusha
  2486. push ds
  2487. push es
  2488. mov bp,sp ;restore stack frame pointer
  2489. SwitchToProtectedMode
  2490. assume ds:DGROUP,es:DGROUP
  2491. ;
  2492. ; Perform fixups on the return register values.
  2493. mov ax,[bp].pmUserAX ;get original function code
  2494. call IntExitCT
  2495. ;
  2496. ; And return to the original caller.
  2497. call LeaveIntHandler
  2498. iret
  2499. ;--------------------------------------------------------
  2500. ; IntEntryCT
  2501. ;--------------------------------------------------------
  2502. assume ds:DGROUP,es:DGROUP,ss:NOTHING
  2503. public IntEntryCT
  2504. IntEntryCT:
  2505. cmp ah,0 ;
  2506. jnz ienCT10
  2507. jmp ienCT80
  2508. ienCT10:
  2509. cmp ah,1 ;
  2510. jnz ienCT20
  2511. mov cx,6 ;
  2512. jmp ienCT70
  2513. ienCT20:
  2514. ienCT50:
  2515. push es
  2516. push ax
  2517. mov ax,40h
  2518. mov es,ax
  2519. ; test byte ptr es:[501h],8h ;if Hmode
  2520. test byte ptr es:[101h],8h ;if Hmode
  2521. jz ienCT90
  2522. ;; test fNHmode,0FFh
  2523. ;; jz ienCT90 ;0=Nmode --->jmp
  2524. ;--------------------- Hmode ----------------------
  2525. cmp ah,3
  2526. jnz ienCT30
  2527. mov cx,4
  2528. jmp ienCT70
  2529. ienCT30:
  2530. cmp ah,4
  2531. jnz ienCT40
  2532. mov cx,12
  2533. jmp ienCT70
  2534. ienCT40:
  2535. cmp ah,5
  2536. jnz ienCT90
  2537. mov cx,12
  2538. ;--------------------- Hmode ----------------------
  2539. ienCT70:
  2540. push ds
  2541. mov si,[bp].pmUserBX ;offset address
  2542. mov ds,[bp].pmUserES ;segment address
  2543. mov di,offset DGROUP:rgbXfrBuf1
  2544. cld
  2545. rep movsb
  2546. pop ds
  2547. ienCT80:
  2548. push ax
  2549. mov ax,segDXDataPM
  2550. mov [bp].intUserES,ax ;segment address
  2551. pop ax
  2552. ;------------------------------------------------------------
  2553. mov [bp].intUserBX,offset DGROUP:rgbXfrBuf1
  2554. ienCT90:
  2555. ret
  2556. ;--------------------------------------------------------
  2557. ; IntExitCT
  2558. ;--------------------------------------------------------
  2559. assume ds:DGROUP,es:DGROUP,ss:NOTHING
  2560. public IntExitCT
  2561. IntExitCT:
  2562. cmp ah,0
  2563. jnz iexCT10
  2564. mov cx,6
  2565. jmp iexCT70
  2566. iexCT10:
  2567. cmp ah,1
  2568. jnz iexCT20
  2569. jmp iexCT80
  2570. iexCT20:
  2571. iexCT50:
  2572. push es
  2573. push ax
  2574. mov ax,40h
  2575. mov es,ax
  2576. ; test byte ptr es:[501h],8h ;if Hmode
  2577. test byte ptr es:[101h],8h ;if Hmode
  2578. jz iexCT90
  2579. ;; test fNHmode,0FFh
  2580. ;; jz iexCT90 ;0=Nmode --->jmp
  2581. ;--------------------- Hmode ----------------------
  2582. cmp ah,3
  2583. jnz iexCT30
  2584. jmp iexCT80
  2585. iexCT30:
  2586. cmp ah,4
  2587. jnz iexCT40
  2588. jmp iexCT80
  2589. iexCT40:
  2590. cmp ah,5
  2591. jnz iexCT90
  2592. jmp iexCT80
  2593. ;--------------------- Hmode ----------------------
  2594. iexCT70:
  2595. push es
  2596. mov di,[bp].pmUserBX ;offset address
  2597. mov es,[bp].pmUserES ;segment address
  2598. mov si,offset DGROUP:rgbXfrBuf1
  2599. cld
  2600. rep movsb
  2601. pop es
  2602. iexCT80:
  2603. push ax
  2604. mov ax,[bp].pmUserES
  2605. mov [bp].intUserES,ax
  2606. ;------------------------------------------------------------
  2607. mov ax,[bp].pmUserBX
  2608. mov [bp].intUserBX,ax
  2609. pop ax
  2610. iexCT90:
  2611. ret
  2612. DXPMCODE ends
  2613. ; -------------------------------------------------------
  2614. subttl INT DCh extended DOS HANDRER
  2615. page
  2616. ; -------------------------------------------------------
  2617. ; PMIntrExDos
  2618. ;--------------------------------------------------------
  2619. DXPMCODE segment
  2620. assume cs:DXPMCODE
  2621. assume ds:NOTHING,es:NOTHING,ss:NOTHING
  2622. public PMIntrExDos
  2623. PMIntrExDos:
  2624. call EnterIntHandler ;build a stack frame and fix up the
  2625. cld ; return address so that the interrupt
  2626. ;service routine will return to us.
  2627. ;
  2628. ; Perform fixups on the entry register values
  2629. call IntEntryED
  2630. ;
  2631. ; Execute the interrupt service routine
  2632. SwitchToRealMode
  2633. assume ss:DGROUP
  2634. pop es
  2635. pop ds
  2636. assume ds:NOTHING,es:NOTHING
  2637. popa
  2638. call rglpfnRmISR[4*0DCh] ;execute the real mode interrupt routine
  2639. pushf
  2640. cli
  2641. cld
  2642. pusha
  2643. push ds
  2644. push es
  2645. mov bp,sp ;restore stack frame pointer
  2646. SwitchToProtectedMode
  2647. assume ds:DGROUP,es:DGROUP
  2648. ;
  2649. ; Perform fixups on the return register values.
  2650. ; mov ax,[bp].pmUserAX ;get original function code
  2651. mov cx,[bp].pmUserCX ;get original function code
  2652. call IntExitED
  2653. ;
  2654. ; And return to the original caller.
  2655. call LeaveIntHandler
  2656. iret
  2657. ;--------------------------------------------------------
  2658. ; IntEntryED
  2659. ;--------------------------------------------------------
  2660. assume ds:DGROUP,es:DGROUP,ss:NOTHING
  2661. public IntEntryED
  2662. IntEntryED:
  2663. cmp cl,0Ch
  2664. jnz ienED10
  2665. jmp ienED80
  2666. ienED10:
  2667. ;;; push cx
  2668. cmp cl,0Dh
  2669. jz ienED
  2670. jmp ienED20
  2671. ienED:
  2672. push cx
  2673. cmp ax,0
  2674. jnz ienED11
  2675. mov cx,386 ;386byte
  2676. jmp ienED70
  2677. ienED11:
  2678. cmp ax,0FFh
  2679. jnz ienED12
  2680. mov cx,786 ;786byte
  2681. jmp ienED70
  2682. ienED12:
  2683. cmp ax,1
  2684. jb ienED13
  2685. cmp ax,0Ah
  2686. ja ienED13
  2687. mov cx,160 ;16*10=160byte
  2688. jmp ienED70
  2689. ienED13:
  2690. cmp ax,0Bh
  2691. jb ienED14
  2692. cmp ax,14h
  2693. ja ienED14
  2694. mov cx,160 ;16*10=160byte
  2695. jmp ienED70
  2696. ienED14:
  2697. cmp ax,15h
  2698. jb ienED15
  2699. cmp ax,1Fh
  2700. ja ienED15
  2701. mov cx,66 ;6*11=66byte
  2702. jmp ienED70
  2703. ienED15:
  2704. cmp ax,20h
  2705. jb ienED16
  2706. cmp ax,24h
  2707. ja ienED16
  2708. mov cx,80 ;16*5=80byte
  2709. jmp ienED70
  2710. ienED16:
  2711. cmp ax,25h
  2712. jb ienED17
  2713. cmp ax,29h
  2714. ja ienED17
  2715. mov cx,80 ;16*5=80byte
  2716. jmp ienED70
  2717. ienED17:
  2718. cmp ax,2Ah
  2719. jb ienED18
  2720. cmp ax,38h
  2721. ja ienED18
  2722. mov cx,240 ;16*15=240byte
  2723. jmp ienED70
  2724. ienED18:
  2725. cmp ax,100h
  2726. jnz ienED20
  2727. mov cx,514 ;2+512=514byte
  2728. jmp ienED70
  2729. ienED20:
  2730. cmp cl,10h
  2731. jnz ienED90
  2732. cmp ah,1
  2733. jnz ienED90
  2734. moji_out:
  2735. mov si,dx
  2736. cmp byte ptr ds:[si],'$'
  2737. ;;;;;;;; cmp byte ptr ds:[dx],'$'
  2738. jz ienED90
  2739. push ds
  2740. mov si,[bp].pmUserDX ;offset address
  2741. mov ds,[bp].pmUserDS ;segment address
  2742. mov di,offset DGROUP:rgbXfrBuf1
  2743. cld
  2744. movsb
  2745. pop ds
  2746. jmp moji_out
  2747. ienED70:
  2748. push ds
  2749. mov si,[bp].pmUserDX ;offset address
  2750. mov ds,[bp].pmUserDS ;segment address
  2751. mov di,offset DGROUP:rgbXfrBuf1
  2752. cld
  2753. rep movsb
  2754. pop ds
  2755. pop cx
  2756. ienED80:
  2757. ;-----------
  2758. push ax
  2759. mov ax,segDXDataPM
  2760. mov [bp].intUserES,ax ;segment address
  2761. pop ax
  2762. ;------------------------------------------------------------
  2763. mov [bp].intUserDX,offset DGROUP:rgbXfrBuf1
  2764. ienED90:
  2765. ret
  2766. ;--------------------------------------------------------
  2767. ; IntExitED
  2768. ;--------------------------------------------------------
  2769. assume ds:DGROUP,es:DGROUP,ss:NOTHING
  2770. public IntExitED
  2771. IntExitED:
  2772. cmp cl,0Ch
  2773. jz iexED
  2774. jmp iexED10
  2775. iexED:
  2776. push cx
  2777. cmp ax,0
  2778. jnz iexED1
  2779. mov cx,386 ;386byte
  2780. jmp iexED70
  2781. iexED1:
  2782. cmp ax,0FFh
  2783. jnz iexED2
  2784. mov cx,786 ;786byte
  2785. jmp iexED70
  2786. iexED2:
  2787. cmp ax,1
  2788. jb iexED3
  2789. cmp ax,0Ah
  2790. ja iexED3
  2791. mov cx,160 ;16*10=160byte
  2792. jmp iexED70
  2793. iexED3:
  2794. cmp ax,0Bh
  2795. jb iexED4
  2796. cmp ax,14h
  2797. ja iexED4
  2798. mov cx,160 ;16*10=160byte
  2799. jmp iexED70
  2800. iexED4:
  2801. cmp ax,15h
  2802. jb iexED5
  2803. cmp ax,1Fh
  2804. ja iexED5
  2805. mov cx,66 ;6*11=66byte
  2806. jmp iexED70
  2807. iexED5:
  2808. cmp ax,20h
  2809. jb iexED6
  2810. cmp ax,24h
  2811. ja iexED6
  2812. mov cx,80 ;16*5=80byte
  2813. jmp iexED70
  2814. iexED6:
  2815. cmp ax,25h
  2816. jb iexED7
  2817. cmp ax,29h
  2818. ja iexED7
  2819. mov cx,80 ;16*5=80byte
  2820. jmp iexED70
  2821. iexED7:
  2822. cmp ax,2Ah
  2823. jb iexED8
  2824. cmp ax,38h
  2825. ja iexED8
  2826. mov cx,240 ;16*15=240byte
  2827. jmp iexED70
  2828. iexED8:
  2829. cmp ax,100h
  2830. jnz iexED10
  2831. mov cx,514 ;2+512=514byte
  2832. jmp iexED70
  2833. iexED10:
  2834. cmp cl,0Dh
  2835. jnz iexED20
  2836. jmp iexED80
  2837. iexED20:
  2838. cmp cl,10h
  2839. jnz iexED90
  2840. cmp ah,1
  2841. jnz iexED90
  2842. jmp iexED80
  2843. iexED70:
  2844. push ds
  2845. mov si,[bp].pmUserDX ;offset address
  2846. mov ds,[bp].pmUserDS ;segment address
  2847. mov di,offset DGROUP:rgbXfrBuf1
  2848. cld
  2849. rep movsb
  2850. pop ds
  2851. pop cx
  2852. iexED80:
  2853. push ax
  2854. ;-----------
  2855. mov ax,[bp].pmUserDS
  2856. mov [bp].intUserDS,ax
  2857. ;------------------------------------------------------------
  2858. mov ax,[bp].pmUserDX
  2859. mov [bp].intUserDX,ax
  2860. pop ax
  2861. iexED90:
  2862. ret
  2863. DXPMCODE ends
  2864. ;/////////////////////////////////////////////////////////////////////////
  2865. ; Hmode no GRAPH ha INT 1Dh(Graph BIOS) niyori byouga sareru.
  2866. ; DOSX deha,
  2867. ;/////////////////////////////////////////////////////////////////////////
  2868. ; -------------------------------------------------------
  2869. ; PMIntr GRAPH BIOS
  2870. ;--------------------------------------------------------
  2871. DXPMCODE segment
  2872. assume cs:DXPMCODE
  2873. assume ds:NOTHING,es:NOTHING,ss:NOTHING
  2874. public PMIntrGraph
  2875. ;///////////////////////////////////////////////////////////////////////
  2876. ;; extrn fNHmode:BYTE ;NHmode
  2877. ;///////////////////////////////////////////////////////////////////////
  2878. PMIntrGraph:
  2879. ;; test fNHmode,0FFh
  2880. ;; jz GBios_Nmode
  2881. call EnterIntHandler ;build a stack frame and fix up the
  2882. cld ; return address so that the interrupt
  2883. ;service routine will return to us.
  2884. ;
  2885. ; Perform fixups on the entry register values
  2886. push ax
  2887. mov ax,[bp].pmUserDS
  2888. call GetSegmentAddress
  2889. shr dx,4
  2890. shl bx,12
  2891. or bx,dx ;bx now = seg of parent psp
  2892. mov [bp].intUserDS,bx
  2893. pop ax
  2894. ;
  2895. ; Execute the interrupt service routine
  2896. SwitchToRealMode
  2897. assume ss:DGROUP
  2898. pop es
  2899. pop ds
  2900. assume ds:NOTHING,es:NOTHING
  2901. popa
  2902. call rglpfnRmISR[4*1Dh] ;execute the real mode interrupt routine
  2903. pushf
  2904. cli
  2905. cld
  2906. pusha
  2907. push ds
  2908. push es
  2909. mov ax,ss
  2910. mov ds,ax
  2911. mov es,ax
  2912. mov bp,sp ;restore stack frame pointer
  2913. SwitchToProtectedMode
  2914. assume ds:DGROUP,es:DGROUP
  2915. ;
  2916. ; Perform fixups on the return register values.
  2917. mov ax,[bp].pmUserAX ;get original function code
  2918. ;/////////////
  2919. push ax
  2920. mov ax,[bp].pmUserDS
  2921. mov [bp].intUserDS,ax
  2922. pop ax
  2923. ;/////////////
  2924. ;
  2925. ; And return to the original caller.
  2926. call LeaveIntHandler
  2927. iret
  2928. DXPMCODE ends
  2929. DXPMCODE segment
  2930. assume cs:DXPMCODE
  2931. assume ds:NOTHING,es:NOTHING,ss:NOTHING
  2932. public PMIntr11dummy
  2933. PMIntr11dummy proc near
  2934. and ax,0FFFDh
  2935. iret
  2936. PMIntr11dummy endp
  2937. DXPMCODE ends
  2938. endif ;NEC_98
  2939. DXPMCODE segment
  2940. assume cs:DXPMCODE
  2941. IFDEF WOW
  2942. public Wow32IntrRefl
  2943. Wow32IntrRefl label word
  2944. ??intnum = 0
  2945. rept 256
  2946. push word ptr ??intnum
  2947. jmp Wow32Intr16Reflector
  2948. ??intnum = ??intnum + 1
  2949. endm
  2950. ;--------------------------------------------------------
  2951. ;
  2952. ; Wow32Intr16Reflector -- This routine reflects a 32 bit
  2953. ; interrupt to a 16 bit handler. It switches to the
  2954. ; dos extender stack to do so.
  2955. ;
  2956. ; Inputs: none
  2957. ; Outputs: none
  2958. ;
  2959. assume ds:nothing,es:nothing,ss:nothing
  2960. public Wow32Intr16Reflector
  2961. Wow32Intr16Reflector proc
  2962. .386p
  2963. push ebp
  2964. mov ebp,esp
  2965. push ds
  2966. push eax
  2967. push ebx
  2968. push edi
  2969. mov ax,ss
  2970. movzx eax,ax
  2971. lar eax,eax
  2972. test eax,(AB_BIG SHL 8)
  2973. jnz w32i16r10
  2974. movzx ebp,bp
  2975. w32i16r10:
  2976. ;
  2977. ; Get a frame on the dosx stack.
  2978. ;
  2979. mov ax,selDgroupPM
  2980. mov ds,ax
  2981. assume ds:DGROUP
  2982. movzx ebx,pbReflStack
  2983. sub pbReflStack,CB_STKFRAME
  2984. ;
  2985. ; Build a frame on the stack
  2986. ;
  2987. sub bx,30
  2988. mov eax, [ebp+6] ; eip
  2989. mov [bx+20], eax
  2990. mov eax, [ebp+10] ; cs
  2991. mov [bx+24], eax
  2992. mov [bx + 18],ss ; ss for stack switch back
  2993. mov eax,ebp
  2994. add eax,6 ; ebp, int number
  2995. mov [bx + 14],eax ; esp for stack switch back
  2996. mov ax,[ebp + 14] ; get flags
  2997. mov [bx + 12],ax
  2998. mov ax,cs
  2999. mov [bx + 10],ax
  3000. mov [bx + 8],offset DXPMCODE:w3216r30
  3001. mov eax,[ebp]
  3002. mov [bx],eax ; put ebp on other stack for pop
  3003. ;
  3004. ; Get handler
  3005. ;
  3006. mov di,[ebp + 4] ; int number
  3007. shl di,2 ; al * 4
  3008. add di,offset DGROUP:Wow16BitHandlers
  3009. mov ax,[di]
  3010. mov [bx + 4],ax ; handler ip
  3011. mov ax,[di + 2]
  3012. mov [bx + 6],ax ; handler cs
  3013. ;
  3014. ; Set up for stack switch
  3015. ;
  3016. push ds
  3017. push ebx
  3018. ;
  3019. ; Restore registers
  3020. ;
  3021. mov ax,[ebp - 2]
  3022. mov ds,ax
  3023. mov eax,[ebp - 6]
  3024. mov ebx,[ebp - 10]
  3025. mov edi,[ebp - 14]
  3026. ;
  3027. ; Switch stacks, restore ebp, and call handler
  3028. ;
  3029. lss esp,[ebp - 20]
  3030. pop ebp
  3031. retf
  3032. ;
  3033. ; N.B. i31_RMCall looks on the stack to get the original user stack pointer.
  3034. ; if you change the stack frame the is passed to the 16 bit int
  3035. ; handlers, that WILL break.
  3036. ;
  3037. w3216r30:
  3038. ;
  3039. ; Switch stacks, deallocate frame from dosx stack and return
  3040. ;
  3041. push ebx
  3042. push eax
  3043. push ds
  3044. lds ebx,[esp+10] ;get ss:esp
  3045. mov eax,[esp+16]
  3046. mov [ebx],eax ;eip
  3047. mov eax,[esp+20]
  3048. mov [ebx+4],eax ;cs
  3049. pop ds
  3050. pop eax
  3051. pop ebx
  3052. lss esp,[esp]
  3053. push ebx
  3054. pushfd
  3055. push eax
  3056. mov ax,ss
  3057. movzx eax,ax
  3058. lar eax,eax
  3059. test eax,(AB_BIG SHL 8) ; is the stack big?
  3060. jnz w32i16r40 ; jif yes, use 32bit operations
  3061. pop eax ; restore regs
  3062. popfd
  3063. rpushfd ; save flags, set virtual int bit
  3064. pop ebx
  3065. push ebp
  3066. movzx ebp, sp
  3067. mov [ebp + 16],ebx ; put flags on iret frame
  3068. pop ebp
  3069. push ds
  3070. mov bx,selDgroupPM
  3071. mov ds,bx
  3072. add pbReflStack,CB_STKFRAME
  3073. pop ds
  3074. pop ebx
  3075. riretd
  3076. w32i16r40: ; stack is big
  3077. pop eax ; restore regs
  3078. popfd
  3079. rpushfd32
  3080. pop ebx
  3081. mov [esp + 12],ebx
  3082. push ds
  3083. mov bx,selDgroupPM
  3084. mov ds,bx
  3085. add pbReflStack,CB_STKFRAME
  3086. pop ds
  3087. pop ebx
  3088. riretd32
  3089. .286p
  3090. Wow32Intr16Reflector endp
  3091. ENDIF
  3092. DXPMCODE ends
  3093. ;
  3094. ;****************************************************************
  3095. end