home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / devddemo.zip / DEMO.ASM < prev    next >
Assembly Source File  |  1991-02-02  |  9KB  |  181 lines

  1.               PAGE      60,131
  2. ;
  3. ;┌───────────────────────────────────────────────────────────────────────────┐
  4. ;│                                                                           │
  5. ;│ Generic Device Device Driver                                              │
  6. ;│                                                                           │
  7. ;└───────────────────────────────────────────────────────────────────────────┘
  8. ;
  9.               .seq                         ;    Use segments in order listed
  10.               .286c                        ;    Must use 286 mode if OS/2
  11.               TITLE     Demo Device Driver
  12. ;
  13. ;┌───────────────────────────────────────────────────────────────────────────┐
  14. ;│                  ATTRIBUTE EQUATES                                        │
  15. ;└───────────────────────────────────────────────────────────────────────────┘
  16. ;
  17. CHR           equ       8000H              ;    Bit set if character device
  18. IDC           equ       4000H              ;    Inter DD communications enabled
  19. NIBM          equ       2000H              ;    Bit set if NON-IBM Block Format
  20. SHAR          equ       1000H              ;    Set to support shrd dev. access
  21. RM            equ       0800H              ;    Set if Removable Media (Blk)
  22. OPN           equ       0800H              ;    Set if Device Open/Close (Char)
  23. OS2           equ       0080H              ;    OS/2 Function Level DD
  24. CLK           equ       0008H              ;    Clock Device
  25. NUL           equ       0004H              ;    Null Device
  26. SCR           equ       0002H              ;    Std Output Device (SCREEN)
  27. KBD           equ       0001H              ;    Std Input Device (KEYBOARD)
  28. ;
  29. ;┌───────────────────────────────────────────────────────────────────────────┐
  30. ;│                  EXTERNAL DECLARATIONS                                    │
  31. ;└───────────────────────────────────────────────────────────────────────────┘
  32. ;
  33.               EXTRN     _strategy_c:far
  34. ;
  35. ;┌───────────────────────────────────────────────────────────────────────────┐
  36. ;│                  DATA SEGMENT                                             │
  37. ;└───────────────────────────────────────────────────────────────────────────┘
  38. ;
  39. ; Device Driver Header must be the first item in the DATA group
  40. ;
  41. ; Automatic Data Grouping
  42. DGROUP        GROUP     NULL,_DATA,CONST,_BSS,LAST_D,FAR_BSS
  43.  
  44. ; Automatic Code Grouping
  45. CGROUP        GROUP     MAINSEG,END_TEXT,_TEXT
  46. ;
  47. NULL          SEGMENT   WORD PUBLIC 'BEGDATA'
  48.               public    header
  49.               public    __acrtused
  50.               public    _devhlp
  51. ;
  52. header        dd        -1                 ; Pointer to next dd header
  53. attrib        dw        OS2+CHR+OPN        ; OS/2 Dev,
  54.                                            ; Char. Device,
  55.                                            ; Open/Close,
  56.                                            ; No IDC support
  57.  
  58.               dw        _strategy          ; Point to Strategy Routine
  59.               dw        0                  ; No IDC
  60.               db        '$DEMO   '         ; Name Field (Must be 8 bytes)
  61.               dq        (0)                ; Reserved for OS/2
  62.               PAGE
  63. _devhlp       dd        ?                  ; DevHlp entry, recv'd on Init Call
  64. ;
  65. __acrtused    dw        0                  ; C .OBJ files want one.  They never
  66.                                            ; use it.
  67. ;
  68. ;┌───────────────────────────────────────────────────────────────────────────┐
  69. ;│ These next empty segments are here to let the .seq command above work like│
  70. ;│ we want.  We want it to put segment LAST_D at the end of the data group.  │
  71. ;│ We do this by saying .seq which says to group them as encountered.  Then  │
  72. ;│ we tell it which ones to group together by using the GROUP command.  Then │
  73. ;│ we put in empty ones for it to encounter.  These have the same names and  │
  74. ;│ attributes as the segments the C compiler will produce.  After we have    │
  75. ;│ shown the assembler and linker all the C procuced segments, we show him   │
  76. ;│ our end of segment marker (LAST_D).  The linker will put all segments with│
  77. ;│ the same name and attributes together and in the order we specify here.   │
  78. ;│                                                                           │
  79. ;│ We then do the same thing with the code segments.  The GROUP command tells│
  80. ;│ which segments to group together, and the order they appear here is the   │
  81. ;│ order they will appear in the .SYS file.                                  │
  82. ;│                                                                           │
  83. ;│ The final 'trick' is to specify the object file from this source file     │
  84. ;│ first when linking.  My method is to put ALL others in a library, and just│
  85. ;│ specify this module's .OBJ file in the linker Automatic Response File     │
  86. ;│ (.ARF).                                                                   │
  87. ;│                                                                           │
  88. ;└───────────────────────────────────────────────────────────────────────────┘
  89. ;
  90. NULL          ENDS
  91. _DATA         SEGMENT   WORD PUBLIC 'DATA'
  92. _DATA         ENDS
  93. CONST         SEGMENT   WORD PUBLIC 'CONST'
  94. CONST         ENDS
  95. FAR_BSS       SEGMENT   WORD PUBLIC 'FAR_BSS'
  96. FAR_BSS       ENDS
  97. _BSS          SEGMENT   WORD PUBLIC 'BSS'
  98. _BSS          ENDS
  99. ;
  100. ;┌───────────────────────────────────────────────────────────────────────────┐
  101. ;│ The next segment MUST be the last data segment to appear.  It marks the   │
  102. ;│ end of the data segment, allowing INIT to calculate how big it is, and    │
  103. ;│ free the rest.                                                            │
  104. ;└───────────────────────────────────────────────────────────────────────────┘
  105. ;
  106. LAST_D        SEGMENT   WORD PUBLIC 'LAST_DATA'
  107.               public    _last_d
  108. _last_d       equ       $                       ; Marks the end of the data
  109. LAST_D        ENDS
  110.               PAGE
  111. ;
  112. ;┌───────────────────────────────────────────────────────────────────────────┐
  113. ;│                  CODE SEGMENT                                             │
  114. ;└───────────────────────────────────────────────────────────────────────────┘
  115. ;
  116. MAINSEG       SEGMENT   WORD PUBLIC 'CODE'
  117. ;
  118.               ASSUME    CS:MAINSEG, DS:DGROUP, ES:nothing
  119.               public    _strategy
  120.               public    __chkstk
  121. ;
  122. ;┌───────────────────────────────────────────────────────────────────────────┐
  123. ;│ The STRATEGY Entry Point.  (ta da)  It pushes the pointer to the request  │
  124. ;│ packet and calls the Strategy routine written in C. This lets the C       │
  125. ;│ function see the pointer as a parameter passed in the usual manner.       │
  126. ;└───────────────────────────────────────────────────────────────────────────┘
  127. ;
  128. _strategy     PROC      FAR
  129. ;
  130.               push      es
  131.               push      bx
  132.               call      _strategy_c           ; call C strategy routine
  133.               pop       bx
  134.               pop       es
  135.               ret
  136. ;
  137. _strategy     ENDP
  138. ;
  139. ;
  140.               PAGE
  141. ;
  142. ;┌───────────────────────────────────────────────────────────────────────────┐
  143. ;│ This is a replacement for the C compiler's stack checking routine.  It    │
  144. ;│ is declared as external by the compiler, but it should never be called    │
  145. ;│ as we compile with all stack probes removed.  If, however, it should get  │
  146. ;│ called, it allocates the local variables like the compiler's __chkstk,    │
  147. ;│ without generating an error if the stack is not big enough.               │
  148. ;└───────────────────────────────────────────────────────────────────────────┘
  149. ;
  150. __chkstk      proc      far
  151.               pop       cx
  152.               pop       dx
  153.               mov       bx,sp
  154.               sub       bx,ax
  155.               mov       sp,bx
  156.               push      dx
  157.               push      cx
  158.               ret
  159. __chkstk      endp
  160. ;
  161. MAINSEG       ENDS
  162. ;
  163. _TEXT         SEGMENT   WORD PUBLIC 'CODE'
  164. _TEXT         ends
  165. ;┌───────────────────────────────────────────────────────────────────────────┐
  166. ;│ The next segment marks the end of the code to be kept.  The C compiler    │
  167. ;│ will call all its segments _TEXT, so they will be combined with this one  │
  168. ;│ Our discardable segments will be tacked on after END_TEXT, and will be    │
  169. ;│ discarded after INIT is done.                                             │
  170. ;└───────────────────────────────────────────────────────────────────────────┘
  171. ;
  172. END_TEXT      SEGMENT   WORD PUBLIC 'CODE'
  173.               public    _last_c
  174. _last_c       equ       $
  175. END_TEXT      ends
  176. ;
  177. INITSEG       SEGMENT   WORD PUBLIC 'CODE'
  178. INITSEG       ends
  179. ;
  180.               END
  181.