home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c220 / 7.ddi / EXAMPLES / DOSEXT / RTAIL2.ASM < prev    next >
Encoding:
Assembly Source File  |  1988-05-29  |  9.0 KB  |  361 lines

  1. ;************************************************************************/
  2. ;*    Copyright (C) 1986-1988 Phar Lap Software, Inc.            */
  3. ;*    Unpublished - rights reserved under the Copyright Laws of the    */
  4. ;*    United States.  Use, duplication, or disclosure by the         */
  5. ;*    Government is subject to restrictions as set forth in         */
  6. ;*    subparagraph (c)(1)(ii) of the Rights in Technical Data and     */
  7. ;*    Computer Software clause at 252.227-7013.            */
  8. ;*    Phar Lap Software, Inc., 60 Aberdeen Ave., Cambridge, MA 02138    */
  9. ;************************************************************************/
  10. ;
  11. ; RTAIL2.ASM - This is the real mode portion of
  12. ; an example program that uses
  13. ; the Microsoft mouse driver, and also demonstrates
  14. ; several techniques for mixing real and protected
  15. ; mode code in the same program.
  16. ;
  17. ; FUNCTIONALITY and IMPLEMENTATION - As described 
  18. ; in PTAIL2.ASM.
  19. ;
  20.  
  21. ;
  22. ; Segment ordering and attributes.
  23. ;
  24. rmcode    segment byte public use16
  25. rmcode    ends
  26. rmdata    segment dword public use16
  27. rmdata    ends
  28. stack    segment dword stack use16
  29. stack    ends
  30.  
  31. ;
  32. ; Constants
  33. ;
  34. TRUE    equ    1
  35. FALSE    equ    0
  36.  
  37. ;
  38. ; Give program a 4K stack
  39. ;
  40. stack    segment
  41.     db    4096 dup(?)
  42. stack    ends
  43.  
  44. ;
  45. ; Data structure for global data that is 
  46. ; stored in the intermode call buffer, where
  47. ; both the real mode and the protected mode
  48. ; program can access it.  This data is
  49. ; initialized by the protected mode program,
  50. ; and modified by the real mode program.
  51. ;
  52. SHARE    struc
  53.     DONEF    dd ?    ; flags when pgm done
  54.     OUTP_CH db ?    ; current output char
  55. SHARE    ends
  56.  
  57. ;
  58. ; Interrupt used to switch by prot mode pgm to
  59. ; transfer control to this real mode program.
  60. ;
  61. REALINT    equ    0F1h
  62.  
  63. ;
  64. ; Global data
  65. ;
  66. rmdata    segment
  67.  
  68. rm_cbuf    dd    ?    ; real mode addr of
  69.                 ; call buffer
  70. rmi_sel    dw    ?    ; original real mode
  71. rmi_offs dw    ?        ; interrupt vec
  72.  
  73. ;
  74. ; Error messages
  75. ;
  76. tailmsg    db    'Bad cmd tail in real mode pgm'
  77.     db    0Dh,0Ah,'$'
  78. chndlrmsg db    'Output char at cursor error'
  79.     db    0Dh,0Ah,'$'
  80.  
  81. rmdata    ends
  82.  
  83. page
  84.     assume    cs:rmcode,ds:rmdata
  85. rmcode    segment    
  86.  
  87. ;***************************************************
  88. ; main - Finishes setting up the interface with the
  89. ;    prot mode program, then sets up the mouse
  90. ;    interrupt handler, then just loops,
  91. ;    processing mouse button hits until the left
  92. ;    one is pressed twice.
  93. ;***************************************************
  94. main    proc    near        ; program entry point
  95.  
  96. ;
  97. ; Get the command tail out of the PSP, then set up DS
  98. ; to point to our data segment.
  99. ;
  100.     mov    bx,ds:80h    ; get 1st word of tail
  101.     mov    ax,rmdata    ; set up DS
  102.     mov    ds,ax            ;
  103.  
  104. ;
  105. ; The command tail should be 1 byte long, and that
  106. ; byte is the interrupt number that is used to call
  107. ; the protected mode program.  Modify the INT 
  108. ; instructions we use to call through to protected mode.
  109. ;
  110.     cmp    bl,1        ; branch if bad len
  111.     jne    short #tail_err        ;
  112.     mov    cs:(byte ptr int_inst1+1),bh
  113.     mov    cs:(byte ptr int_inst2+1),bh
  114.  
  115. ;
  116. ; Call our init routine to finish setting up the
  117. ; communication interface with the prot mode pgm,
  118. ; and to set up the mouse interrupt handler.
  119. ;
  120.     call    init
  121.  
  122. ;
  123. ; Now just loop until the done flag is set by
  124. ; the interrupt handlers.
  125. ;
  126.     les    bx,rm_cbuf    ; get ptr to buffer
  127. #wait:
  128.     cmp    dword ptr es:[bx].DONEF,FALSE
  129.     je    #wait
  130.  
  131.     call    cleanup        ; clean up for exit
  132.     mov    al,0        ; return success
  133.  
  134. #exit:
  135.     mov    ah,4Ch        ; exit to parent pgm
  136.     int    21h            ;
  137.  
  138. #tail_err:
  139.     lea    dx,tailmsg
  140. #err:
  141.     mov    ah,9        ; output error msg
  142.     int    21h            ;
  143.     mov    al,1        ; return error
  144.     jmp    #exit            ;
  145.  
  146. main    endp
  147.  
  148. ;***************************************************
  149. ; init - This routine takes over the interrupt vector
  150. ;    we use to call thru to real mode from the 
  151. ;    prot mode program, then calls the prot mode
  152. ;    program to give it the vector number and to
  153. ;    get the address of the intermode call buffer,
  154. ;    and then calls the mouse driver to set up
  155. ;    the character input mode routine as the
  156. ;    mouse handler for when a mouse button gets
  157. ;    pressed.
  158. ;***************************************************
  159. init    proc    near
  160.  
  161.     push    es        ; save regs
  162.  
  163. ;
  164. ; Save the current real mode vector for the interrupt
  165. ; we will use to switch from prot mode to real mode,
  166. ; then take over the interrupt vector to point to
  167. ; our routine.
  168. ;
  169.     mov    al,REALINT    ; save original
  170.     mov    ah,35h            ; real mode
  171.     int    21h            ; vector
  172.     mov    ax,es            ;
  173.     mov    rmi_sel,ax        ;
  174.     mov    rmi_offs,bx        ;
  175.     mov    al,REALINT    ; set up our
  176.     mov    ah,25h            ; handler
  177.     lea    dx,from_prot        ;
  178.     push    ds            ;
  179.     push    cs            ;
  180.     pop    ds            ;
  181.     int    21h            ;
  182.     pop    ds            ;
  183.  
  184. ;
  185. ; Call thru to prot mode to get the addr of the 
  186. ; intermode call buffer, and to give the prot mode
  187. ; program the number of the interrupt we took over.
  188. ;
  189.     mov    eax,1        ; function number
  190.     mov    bl,REALINT    ; interrupt number
  191.     mov    cx,cs        ; code segment addr
  192. int_inst1:
  193.     int    0        ; call prot mode
  194.     mov    rm_cbuf,ebx    ; save addr of buf
  195.  
  196. ;
  197. ; Call the mouse driver to set up the character mode
  198. ; handler as the mouse handler when a button is
  199. ; pressed.
  200. ;
  201.     push    cs        ; handler addr in
  202.     pop    es            ; ES:DX
  203.     lea    dx,ch_hndlr        ;
  204.     mov    cx,0Ah        ; interrupt mask
  205.     mov    ax,12        ; set up handler
  206.     int    33h            ;
  207.  
  208. #exit:
  209.     pop    es        ; restore regs &
  210.     ret                ; exit
  211.  
  212. init    endp
  213.  
  214. ;***************************************************
  215. ; cleanup - All this routine does is restore the 
  216. ;    original vector for the interrupt we took
  217. ;    over.
  218. ;***************************************************
  219. cleanup    proc    near
  220.     mov    al,REALINT    ; restore original
  221.     mov    ah,25h            ; interrupt
  222.     mov    dx,rmi_offs        ; vector
  223.     push    ds            ;
  224.     push    rmi_sel            ;
  225.     pop    ds            ;
  226.     int    21h            ;
  227.     pop    ds            ;
  228.     ret            ; exit
  229. cleanup    endp
  230.  
  231. ;***************************************************
  232. ; from_prot - This is the routine that gets control
  233. ;    when the prot mode program issues the software
  234. ;    interrupt that we took over.  This routine
  235. ;    only performs one function, so there are no
  236. ;    function codes.  It sets up the toggle
  237. ;    mode routine as the mouse handler.
  238. ;
  239. ; IN:    Nothing
  240. ; OUT:    AX-DX = destroyed
  241. ;***************************************************
  242.     assume    nothing,cs:rmcode
  243. from_prot proc near
  244.     push    es        ; save regs
  245.     push    cs        ; handler addr in
  246.     pop    es            ; ES:DX
  247.     lea    dx,tog_hndlr        ;
  248.     mov    cx,0Ah        ; interrupt mask
  249.     mov    ax,12        ; set up handler
  250.     int    33h            ;
  251.     pop    es        ; restore regs &
  252.     iret                ; exit
  253. from_prot endp
  254.  
  255. ;***************************************************
  256. ; ch_hndlr - This routine is invoked by the mouse
  257. ;    driver when either mouse button is pressed,
  258. ;    and when we are in character output mode.
  259. ;    This handler just calls a protected mode
  260. ;    routine to process the interrupt.  Since
  261. ;    this is a hardware interrupt handler, it is 
  262. ;     obligated to preserve all 32-bit registers.
  263. ;
  264. ;    This routine demonstrates passing values
  265. ;    both on the stack and in registers to a
  266. ;    protected mode routine invoked with a
  267. ;    software interrupt.
  268. ;***************************************************
  269.     assume    nothing,cs:rmcode
  270. ch_hndlr proc    far
  271.     push    eax        ; save regs wiped
  272.     push    ebx            ; out by prot
  273.     push    ecx            ; mode routine
  274.     push    edx            ;
  275.  
  276. ;
  277. ; To call the prot mode routine, all we do is push
  278. ; any params to the routine onto the stack, then
  279. ; issue the software interrupt.
  280. ;
  281.     push    ax        ; param = cond. mask
  282.     mov    eax,2        ; mouse hit function
  283. int_inst2:
  284.     int    0        ; call prot mode routine
  285.     add    sp,2        ; pop parameters
  286.     cmp    eax,TRUE    ; branch if error
  287.     je    short #err        ;
  288.  
  289. #exit:
  290.     pop    edx        ; restore regs &
  291.     pop    ecx            ; exit
  292.     pop    ebx            ;
  293.     pop    eax            ;
  294.     ret                ; 
  295.  
  296. #err:
  297.     push    ds        ; save DS
  298.     mov    ax,rmdata    ; set up data seg
  299.     mov    ds,ax            ;
  300.     assume    ds:rmdata        ;
  301.     lea    dx,chndlrmsg    ; output error msg
  302.     mov    ah,9            ;
  303.     int    21h            ;
  304.     pop    ds        ; restore DS and exit
  305.     jmp    #exit            ;
  306. ch_hndlr endp
  307.  
  308. ;***************************************************
  309. ; tog_hndlr - This routine is invoked by the mouse
  310. ;    driver when either mouse button is pressed,
  311. ;    and we are in toggle mode (the left mouse
  312. ;    button was the last one pressed).
  313. ;    If the left button has been pressed, we
  314. ;    set the done flag.  If the right button has
  315. ;    been pressed, we toggle the character that
  316. ;    gets output between '*' and ' ', and then
  317. ;    restore ch_hndlr as the mouse interrupt
  318. ;    handler.  Since this is a hardware 
  319. ;    interrupt handler, it is obligated to 
  320. ;    preserve all 32-bit registers.
  321. ;***************************************************
  322.     assume    nothing,cs:rmcode
  323. tog_hndlr proc    far
  324.     push    ds        ; save regs
  325.     push    es            ;
  326.  
  327.     push    rmdata        ; set up data segment
  328.     pop    ds            ;
  329.     assume    ds:rmdata        ;
  330.     lds    bx,rm_cbuf    ; set up DS:BX to point
  331.     assume    ds:nothing        ; to call buffer
  332.  
  333.     test    ax,2        ; branch if left button
  334.     jz    short #right        ; not pressed
  335.     mov    [bx].DONEF,TRUE    ; set done flag & exit
  336.     jmp    short #exit        ;
  337.  
  338. #right:
  339.     mov    al,' '        ; assume char = ' '
  340.     cmp    [bx].OUTP_CH,'*' ; toggle output char
  341.     je    short #space        ;
  342.     mov    al,'*'            ;
  343. #space:                    ;
  344.     mov    [bx].OUTP_CH,al        ;
  345.     mov    ax,cs        ; Restore ch_hndlr
  346.     mov    es,ax            ; as mouse
  347.     lea    dx,ch_hndlr        ; handler
  348.     mov    cx,0Ah            ;
  349.     mov    ax,12            ;
  350.     int    33h            ;
  351.  
  352. #exit:
  353.     pop    es        ; restore regs &
  354.     pop    ds            ; exit
  355.     ret                ;
  356. tog_hndlr endp
  357.  
  358. rmcode    ends
  359.  
  360.     end main        ; program entry point
  361.