home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / slice.zip / SLICE.ASM < prev    next >
Assembly Source File  |  1993-10-18  |  10KB  |  364 lines

  1. ;========================================================================
  2. ;
  3. ;  SLICE.ASM
  4. ;
  5. ;  Provides a generic time slicing function for all DOS multi-taskers I
  6. ;  know or care about.
  7. ;
  8. ;  Note that this library is Turbo Assembler specific, since I have long
  9. ;  since weaned myself from MASM's brain-dead memory addressing syntax.
  10. ;
  11. ;  This library is designed to be easily extended; for each new
  12. ;  multi-tasker supported, you need to write a detect routine and a
  13. ;  time-slice routine.
  14. ;
  15. ;  Your detection function will take no input, and should return with
  16. ;  carry set if the associated multi-tasker is detected. This routine
  17. ;  may safely alter register AX. No other registers should be altered.
  18. ;
  19. ;  The time-slice routine will take no input and give up a "standard"
  20. ;  timeslice for the associated multi-tasker. This routine may safely
  21. ;  alter registers AX, BX and DS. No other registers should be altered.
  22. ;
  23. ;  Once you have such routines written, add their addresses to the
  24. ;  arrays detect_func and slice_func below. Increment the
  25. ;  NumMultitaskers equate, and you're done.
  26. ;
  27. ;  This library placed in the public domain by Kevin Vigor, 1/5/93.
  28. ;  I would, however, appreciate it if you do the following two things:
  29. ;
  30. ;   1: If you distribute an altered version of this source, please add to
  31. ;      this header a log of your changes;
  32. ;
  33. ;   2: If you discover any bugs or extend this library, please send a copy
  34. ;      of your changes to me at one of the below addresses:
  35. ;
  36. ;           Compuserve: 72500,3705
  37. ;           Internet:   kevin@elvis.wicat.com (preferred address)
  38. ;                       72500.3705@compuserve.com
  39. ;
  40. ; Changes:
  41. ;
  42. ; 3/7/93, Kevin Vigor:
  43. ; NEAR function over-rides added to allow use of LARGE and HUGE models.
  44. ;
  45. ; 10/17/93, Kevin Vigor:
  46. ; Support for OS/2 2.1 added. Thanks to Kurt Westerfield and Peter Fitzsimmons.
  47. ;
  48. ;========================================================================
  49.  
  50.  
  51. IDEAL                   ; Requires Turbo Assembler.
  52.  
  53. MODEL LARGE             ; This may be changed to any model safely. Note,
  54.                         ; however, that you will not be able to link
  55.                         ; this routine to a .COM, since it makes explicit
  56.                         ; segment refrences. This is just laziness; I
  57.                         ; haven't bothered to do all the ifdef'ing.
  58.  
  59. LOCALS                  ; Allow local symbols starting with @@
  60.  
  61. DATASEG
  62.  
  63. ; Define known multitaskers.
  64. None        equ 0
  65. DesqView    equ 1
  66. Windows_3x  equ 2
  67. OS2_20      equ 3
  68. OS2_21_plus equ 4
  69.  
  70. NumMultitaskers EQU 4                           ; Do not include 'None'
  71.  
  72. current_tasker  dw 0                            ; Detected multi-tasker
  73.  
  74. ; Table of detection routines.
  75.  
  76. detect_func     DW  OFFSET @code:dummy_detect
  77.                 DW  OFFSET @code:Desqview_detect
  78.                 DW  OFFSET @code:Windows_3X_detect
  79.                 DW  OFFSET @code:OS2_20_detect
  80.                 DW  OFFSET @code:OS2_21_detect
  81.  
  82. ; Table of time-slicing functions.
  83.  
  84. slice_func      DW OFFSET @code:dummy_slice
  85.                 DW OFFSET @code:Desqview_slice
  86.                 DW OFFSET @code:Win_3x_or_OS2_20_slice
  87.                 DW OFFSET @code:Win_3x_or_OS2_20_slice
  88.                 DW OFFSET @code:OS2_21_slice
  89.  
  90. CODESEG
  91.  
  92. PUBLIC _detect_multitasker, _timeslice
  93.  
  94. ;; Detection routines: return with carry set if the appropiate tasker is
  95. ;; detected and clear if not.
  96.  
  97. PROC dummy_detect NEAR  ; SHould never be called, but does no harm.
  98. clc                     ; Always fail.
  99. ret
  100. ENDP
  101.  
  102. PROC    Desqview_detect NEAR ; Return with carry set if Desqview detected.
  103. ;
  104. ; This routine is based on information in the Desqview version 2.x manual.
  105. push    ax
  106. push    bx
  107. push    cx
  108. push    dx
  109.  
  110. mov     cx, 'DE'
  111. mov     dx, 'SQ'
  112. mov     ax, 02B01h                  ; DOS set date function.
  113. int     021h
  114. cmp     al, 0FFh                    ; Did DOS report the invalid date?
  115. jnz     @@desqview                  ; If not, we've got Desqview.
  116.  
  117. clc                                 ; Report failure.
  118.  
  119. @@clean_stack:
  120. pop     dx
  121. pop     cx
  122. pop     bx
  123. pop     ax
  124. ret
  125.  
  126. @@desqview:
  127.  
  128. ; BH = Desqview major version, BL = Desqview minor version. I have no idea
  129. ; at what version the timeslicing calls became available, so I just assume
  130. ; they are supported. If this is an invalid assumption, this would be the
  131. ; place to test.
  132.  
  133. stc                                 ; Report sucess.
  134. jmp     short @@clean_stack         ; and exit.
  135.  
  136. ENDP    ; Desqview_detect.
  137.  
  138. PROC    Windows_3X_detect NEAR
  139. ; Note: this function detects Windows 3.x in enhanced mode only.
  140. ; I am not a Windows guru (or even user), but I believe there is no
  141. ; capability for time-slicing in standard or real modes, therefore this
  142. ; function is sufficient for the purposes of this library.
  143. ; I am basing this function on the fine book PC Interrupts, which lists
  144. ; a number of magic values which mean Windows 3.x enhanced mode is not running.
  145.  
  146. push    ax
  147.  
  148. mov     ax, 01600h
  149. int     02Fh
  150.  
  151. cmp     al, 00h
  152. jz      @@no_Windows
  153.  
  154. cmp     al, 080h
  155. jz      @@no_Windows
  156.  
  157. cmp     al, 01h                 ; Windows/386 2.x; not supported.
  158. jz      @@no_windows
  159.  
  160. cmp     al, 0FFh                ; Windows/386 2.x; not supported.
  161.  
  162. ; If AL is none of the above values, it is the Windows major version number.
  163.  
  164. cmp     al, 03h                 ; At least Win 3.0?
  165. jb      @@no_windows
  166.  
  167. stc                             ; Yes, report sucess.
  168. pop     ax
  169. ret
  170.  
  171. @@no_windows:
  172. clc                             ; Report failure.
  173. pop     ax
  174. ret
  175. ENDP
  176.  
  177. PROC    OS2_20_detect NEAR
  178. ; We check for the presence of OS/2 by checking the reported DOS version.
  179. ; If the major version is 20 and the minor version is less than 10,
  180. ; we assume we're in an OS/2 2.0 DOS box.
  181.  
  182. push    ax
  183. push    cx
  184.  
  185. mov     ah, 030h                    ; DOS get version fn.
  186. int     021h
  187.  
  188. cmp     al, 014h                    ; 20 decimal.
  189. jb      @@no_OS2_20
  190.  
  191. cmp     ah, 0Ah                     ; Is minor ver. > 10?
  192. jae     @@no_OS2_20
  193.  
  194. stc                                 ; Report sucess.
  195.  
  196. @@clean_stack:
  197. pop     cx
  198. pop     ax
  199. ret
  200.  
  201. @@no_OS2_20:
  202. clc                                 ; Report failure.
  203. jmp     short @@clean_stack
  204.  
  205. ENDP
  206.  
  207. PROC OS2_21_detect NEAR
  208. ; We check for the presence of OS/2 by checking the reported DOS version.
  209. ; If the major version is 20 and the minor version is greater than or equal to
  210. ; 10, we assume we're in an OS/2 2.0 DOS box.
  211.  
  212. push    ax
  213. push    cx
  214.  
  215. mov     ah, 030h                    ; DOS get version fn.
  216. int     021h
  217.  
  218. cmp     al, 014h                    ; 20 decimal.
  219. jb      @@no_OS2_21
  220.  
  221. cmp     ah, 0Ah                     ; Is minor ver. < 10?
  222. jb      @@no_OS2_21
  223.  
  224. stc                                 ; Report sucess.
  225.  
  226. @@clean_stack:
  227. pop     cx
  228. pop     ax
  229. ret
  230.  
  231. @@no_OS2_21:
  232. clc                                 ; Report failure.
  233. jmp     short @@clean_stack
  234.  
  235. ENDP
  236.  
  237. ;; Time slicing routines for each tasker.
  238.  
  239. PROC    dummy_slice NEAR            ; Should never be called, but does no harm.
  240. ret
  241. ENDP
  242.  
  243. PROC    Desqview_slice  NEAR        ; Give up a slice under Desqview.
  244.  
  245. ASSUME  cs:@code, ds:nothing, es:nothing
  246. mov     ax, 0101Ah                      ; Switch to DV's stack.
  247. int     015h
  248. mov     ax, 01000h                      ; Give up time-slice.
  249. int     015h
  250. mov     ax, 01025h                      ; Restore local stack.
  251. int     015h
  252. ret
  253. ENDP
  254.  
  255. PROC    Win_3x_or_OS2_20_slice NEAR
  256.  
  257. ; This call works under either Windows 3.x in Enhanced mode, or OS/2 2.0
  258.  
  259. ASSUME  ds:@code, ds:nothing, es:nothing
  260. mov     ax, 01680h                      ; Win 3.x / OS/2 2.x timeslice call.
  261. int     02Fh
  262. ret
  263. ENDP
  264.  
  265. PROC    OS2_21_slice NEAR       ; Give up a slice under OS/2 2.1 (and, I hope,
  266. push    dx                      ; future versions)
  267.  
  268. xor     dx, dx                  ; DX:AX = number of milliseconds to give up;
  269. mov     ax, 01h                 ; 0 = rest of current timeslice, allegedly, but
  270.                                 ; doesn't seem to work in my tests.
  271.  
  272. sti                             ; Ensure that interrupts are on (else we'll
  273.                                 ; wait forever)
  274.  
  275. hlt                             ; Call OS/2
  276. db      035h, 0CAh              ; Signature to specify DosSleep to OS/2.
  277.  
  278. pop     dx
  279. ret
  280.  
  281. ret
  282. ENDP
  283.  
  284.  
  285. PROC _detect_multitasker
  286. ; Tries to find a multi-tasker.
  287. ; Returns the ID in AX, and sets up the internal data to call _timeslice.
  288. ;
  289. ; Note that this function can be safely called from Turbo/Borland C. I have
  290. ; no idea about other compilers.
  291.  
  292. push    ds
  293. push    bx
  294. push    cx
  295.  
  296. ASSUME  cs:@code, ds:nothing, es:nothing
  297. mov     ax, @data
  298. mov     ds, ax
  299. ASSUME  ds:@data
  300.  
  301. mov     cx, NumMultitaskers     ; Number of routines to try.
  302. xor     ax, ax
  303.  
  304. @@detect_loop:
  305. inc     ax
  306.  
  307. ; AX holds the number of the detection routine to try.
  308. push    ax
  309. shl     ax, 1
  310. mov     bx, ax                  ; BX = AX * 2
  311.  
  312. call    [detect_func + bx]      ; Call this function.
  313. pop     ax                      ; Restore AX.
  314. jc      @@found_one             ; quit now if we hit one.
  315.  
  316. loop    @@detect_loop           ; Go through all known detection routines.
  317.  
  318. xor     ax, ax                  ; Signal failure.
  319. jmp     short @@clean_stack     ; and exit.
  320.  
  321. @@found_one:
  322. mov     [current_tasker], ax
  323.  
  324. @@clean_stack:
  325. pop     cx
  326. pop     bx
  327. pop     ds
  328.  
  329. ASSUME  ds:nothing
  330.  
  331. ret
  332. ENDP
  333.  
  334. PROC _timeslice
  335. ; Give up a timeslice. Depends on having the current_tasker global set by
  336. ; a call to detect_multitasker. However, will call dummy_slice and do no
  337. ; harm if detect_multitasker has not been called.
  338. ;
  339. ; Note that this function can be safely called from Turbo/Borland C. I have
  340. ; no idea about other compilers.
  341.  
  342. push    ds
  343. push    ax
  344. push    bx
  345.  
  346. ASSUME cs:@code, ds:nothing, es:nothing
  347. mov     ax, @data
  348. mov     ds, ax
  349. ASSUME  ds:@data
  350.  
  351. mov     ax, [current_tasker]
  352. shl     ax, 1                       ; BX = AX * 2
  353. mov     bx, ax
  354.  
  355. call    [slice_func + bx]           ; Call appropiate time-slice function.
  356.  
  357. pop     bx
  358. pop     ax
  359. pop     ds
  360. ret
  361. ENDP
  362.  
  363. END
  364.