home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / progm / ctask.zip / TSKDOS.ASM < prev    next >
Assembly Source File  |  1988-03-01  |  19KB  |  977 lines

  1. ;
  2. ;    CTask - DOS access module.
  3. ;
  4. ;    Public Domain Software written by
  5. ;        Thomas Wagner
  6. ;        Patschkauer Weg 31
  7. ;        D-1000 Berlin 33
  8. ;        West Germany
  9. ;
  10. ;
  11. ; The DOS interrupt (and the related direct disk I/O interrupts) are
  12. ; not reentrant. Access to DOS thus has to be channelled such that no
  13. ; two tasks use DOS services simultaneously. However, there is one
  14. ; exception to this rule. Whenever DOS is waiting for the keyboard, it
  15. ; issues a special interrupt, INT 28h, to signal that background
  16. ; processing for functions > 0Ch may be performed. This is used in the
  17. ; DOS interface for CTask in the following manner:
  18. ;
  19. ;   A task issuing a DOS interrupt will request one of two resources:
  20. ;   "lower_dos" for functions <= 0C, "upper_dos" for functions > 0C.
  21. ;   If a task gets access to "lower_dos", it will also request the
  22. ;   "upper_dos" resource to lock out other tasks from interrupting.
  23. ;   This "upper_dos" resource is shortly released on each INT 28, and
  24. ;   then immediately reclaimed, with task priority temporarily raised
  25. ;   to the maximum value. The first task waiting to execute a 
  26. ;   function > 0C will thus be scheduled to execute the request, but
  27. ;   the resource will be reassigned to the INT 28 handler as soon as
  28. ;   this request terminates, so the waiting task will not be delayed too
  29. ;   long.
  30. ;
  31. ; There are two additional safety measures which have to be taken to
  32. ; avoid getting into conflicts with other resident background programs,
  33. ; especially the DOS PRINT background spooler:
  34. ;
  35. ;   Before requesting any resource, the status of the DOS critical section
  36. ;   flag is checked. If this flag is set, the task is made waiting for
  37. ;   the flag to be cleared.
  38. ;   Only the task that set the flag will be allowed access to DOS.
  39. ;
  40. ;   Before actually executing the request, the status of the DOS in-use
  41. ;   flag is checked. If this flag is set, the task enters a busy waiting
  42. ;   loop, calling the scheduler so that the processor is not tied up.
  43. ;
  44.     name    tskdos
  45.     .model    large
  46. ;
  47.     public    _tsk_install_dos
  48.     public    _tsk_remove_dos
  49. ;
  50. ;
  51.     include    tsk.mac
  52. ;
  53. CSECT        =    2ah    ; Critical Section Interrupt
  54. get_in_use_flag    =    34h    ; DOS-function to get in_use_flag address
  55. ;
  56. ;
  57. intseg    segment at 0
  58.         org    20h*4
  59. termoff        dw    ?    ; program terminate vector
  60. termseg        dw    ?
  61.         org    21h*4
  62. idosoff        dw    ?    ; dos interrupt
  63. idosseg        dw    ?
  64.         org    25h*4
  65. absreadoff    dw    ?    ; absolute disk read
  66. absreadseg    dw    ?
  67.         org    26h*4
  68. abswriteoff    dw    ?    ; absolute disk write
  69. abswriteseg    dw    ?
  70.         org    27h*4
  71. keepoff        dw    ?    ; Terminate but stay resident
  72. keepseg        dw    ?
  73.         org    28h*4
  74. idleoff        dw    ?    ; dos idle interrupt
  75. idleseg        dw    ?
  76.         org    CSECT*4
  77. csectoff    dw    ?    ; dos critical section
  78. csectseg    dw    ?
  79. ;
  80. intseg    ends
  81. ;
  82. ;----------------------------------------------------------------------------
  83. ;
  84. ;    Variables
  85. ;
  86.     .data
  87. ;
  88.     extrn    _tsk_current: dword
  89. ;
  90. term_err_msg    db    0dh,0ah,"Program terminated - CTask uninstalled"
  91.         db    0dh,0ah,'$'
  92. ;
  93. idle_active    db    0            ; Idle-Interrupt active
  94. dos310        db    0        ; DOS version >= 3.10
  95. ;
  96.     .data?
  97. ;
  98. in_use        dd    ?        ; Adress of DOS in-use-flag
  99. ;
  100. lower_dos    resource <>
  101. upper_dos    resource <>
  102. critical    flag <>
  103. ;
  104. idle_ss        dw    ?        ; Stack save
  105. idle_sp        dw    ?
  106. ;
  107.         dw    256 dup(?)    ; Stack for IDLE-Interrupt
  108. local_stack    label    word
  109. ;
  110.     .code
  111. ;
  112. ;    Original Interrupt-Entries
  113. ;
  114. savtermoff    dw    ?        ; Terminate vector save
  115. savtermseg    dw    ?
  116. ;
  117. savdos        label    dword        ; original DOS-Entry
  118. savdosoff    dw    ?
  119. savdosseg    dw    ?
  120. ;
  121. savidle        label    dword        ; original IDLE-Entry
  122. savidleoff    dw    ?
  123. savidleseg    dw    ?
  124. ;
  125. savcsect    label    dword        ; Critical Section save
  126. savcsectoff    dw    ?
  127. savcsectseg    dw    ?
  128. ;
  129. savabsread    label    dword        ; Absolute Disk Read save
  130. savabsreadoff    dw    ?
  131. savabsreadseg    dw    ?
  132. ;
  133. savabswrite    label    dword        ; Absolute Disk Write save
  134. savabswriteoff    dw    ?
  135. savabswriteseg    dw    ?
  136. ;
  137. savkeepoff    dw    ?        ; Terminate resident vector save
  138. savkeepseg    dw    ?
  139. ;
  140. critsect_active    db    0        ; DOS Critical Section active
  141. ctask_active    db    0        ; CTask DOS call active
  142. crit_task    dd    ?        ; Task requesting critical section
  143. ;
  144. ;
  145. dos    macro
  146.     pushf
  147.     cli
  148.     call    cs:savdos
  149.     endm
  150. ;
  151. ;---------------------------------------------------------------------------
  152. ;
  153.     .code
  154. ;
  155.     extrn    _create_resource: far
  156.     extrn    _delete_resource: far
  157.     extrn    _request_resource: far
  158.     extrn    _release_resource: far
  159.     extrn    _create_flag: far
  160.     extrn    _delete_flag: far
  161.     extrn    _set_flag: far
  162.     extrn    _clear_flag: far
  163.     extrn    _wait_flag_clear: far
  164.     extrn    _remove_tasker: far
  165.     extrn    scheduler: far
  166. ;
  167. ;
  168. ;    void tsk_install_dos (void)
  169. ;
  170. ;        Install DOS handler
  171. ;
  172. _tsk_install_dos    proc
  173. ;
  174. ;    create needed resources & flags
  175. ;
  176.     mov    ax,offset upper_dos
  177.     push    ds
  178.     push    ax
  179.     call    _create_resource
  180.     add    sp,4
  181. ;
  182.     mov    ax,offset lower_dos
  183.     push    ds
  184.     push    ax
  185.     call    _create_resource
  186.     add    sp,4
  187.     mov    ax,offset critical
  188.     push    ds
  189.     push    ax
  190.     call    _create_flag
  191.     add    sp,4
  192. ;
  193. ;    Get the address of DOS's in_use-flag. This flag indicates that
  194. ;    DOS is already active. This might happen if there are other
  195. ;    background tasks, like popups or print spoolers, active in
  196. ;    parallel to CTask.
  197. ;    Since beginning with DOS 3.10 the flag is a WORD value, we also
  198. ;    have to check for the DOS version.
  199. ;    
  200.     mov    ah,get_in_use_flag
  201.     int    21h
  202.     mov    word ptr in_use,bx
  203.     mov    word ptr in_use+2,es
  204. ;
  205.     mov    ah,30h
  206.     int    21h
  207.     cmp    ah,3
  208.     jb    not_dos3
  209.     cmp    al,10
  210.     jb    not_dos3
  211.     inc    dos310
  212.     dec    word ptr in_use        ; adjust offset for DOS >= 3.10
  213. not_dos3:
  214. ;
  215. ;    Save old interrupt vectors
  216. ;
  217.         push    es
  218.     xor    ax,ax
  219.     mov    es,ax
  220. ;
  221.         assume  es:intseg
  222. ;
  223.     mov    ax,termoff        ; DOS
  224.     mov    savtermoff,ax
  225.     mov    ax,termseg
  226.     mov    savtermseg,ax
  227. ;
  228.     mov    ax,idosoff        ; DOS
  229.     mov    savdosoff,ax
  230.     mov    ax,idosseg
  231.     mov    savdosseg,ax
  232. ;
  233.     mov    ax,idleoff        ; IDLE
  234.     mov    savidleoff,ax
  235.     mov    ax,idleseg
  236.     mov    savidleseg,ax
  237. ;
  238.     mov    ax,csectoff        ; Critical Section
  239.     mov    savcsectoff,ax
  240.     mov    ax,csectseg
  241.     mov    savcsectseg,ax
  242. ;
  243.     mov    ax,absreadoff        ; Absolute Disk read
  244.     mov    savabsreadoff,ax
  245.     mov    ax,absreadseg
  246.     mov    savabsreadseg,ax
  247. ;
  248.     mov    ax,abswriteoff        ; Absolute Disk write
  249.     mov    savabswriteoff,ax
  250.     mov    ax,abswriteseg
  251.     mov    savabswriteseg,ax
  252. ;
  253.     mov    ax,keepoff        ; Terminate Resident
  254.     mov    savkeepoff,ax
  255.     mov    ax,keepseg
  256.     mov    savkeepseg,ax
  257. ;
  258. ;    Enter new Interrupt-Entries
  259. ;
  260.     cli
  261.     mov    idosoff,offset dosentry        ; DOS-Entry
  262.     mov    idosseg,cs
  263.     mov    idleoff,offset idleentry    ; Idle-Entry
  264.     mov    idleseg,cs
  265.     mov    termoff,offset terminate_int    ; Terminate Process Entry
  266.     mov    termseg,cs
  267.     mov    csectoff,offset critsectint    ; Critical Section Entry
  268.     mov    csectseg,cs
  269.     mov    keepoff,offset keep_int        ; Keep Process Entry
  270.     mov    keepseg,cs
  271.     mov    absreadoff,offset absread_int    ; Absolute Disk Read Entry
  272.     mov    absreadseg,cs
  273.     mov    abswriteoff,offset abswrite_int    ; Absolute Disk Write Entry
  274.     mov    abswriteseg,cs
  275.     sti
  276.         pop     es
  277. ;
  278.     ret
  279. ;
  280.     assume    es:nothing
  281. ;
  282. _tsk_install_dos    endp
  283. ;
  284. ;
  285. ;    void tsk_remove_dos (void)
  286. ;
  287. ;        Un-install DOS handler
  288. ;
  289. _tsk_remove_dos    proc
  290. ;
  291. ;    Delete resources & flags
  292. ;
  293.     mov    ax,offset upper_dos
  294.     push    ds
  295.     push    ax
  296.     call    _delete_resource
  297.     add    sp,4
  298. ;
  299.     mov    ax,offset lower_dos
  300.     push    ds
  301.     push    ax
  302.     call    _delete_resource
  303.     add    sp,4
  304. ;
  305.     mov    ax,offset critical
  306.     push    ds
  307.     push    ax
  308.     call    _delete_flag
  309.     add    sp,4
  310. ;
  311.         push    es
  312.     xor    ax,ax
  313.     mov    es,ax
  314. ;
  315.         assume  es:intseg
  316. ;
  317. ;    Restore interrupt entries
  318. ;
  319.     cli
  320.     mov    ax,savtermoff
  321.     mov    termoff,ax
  322.     mov    ax,savtermseg
  323.     mov    termseg,ax
  324. ;
  325.     mov    ax,savdosoff
  326.     mov    idosoff,ax
  327.     mov    ax,savdosseg
  328.     mov    idosseg,ax
  329. ;
  330.     mov    ax,savidleoff
  331.     mov    idleoff,ax
  332.     mov    ax,savidleseg
  333.     mov    idleseg,ax
  334. ;
  335.     mov    ax,savcsectoff
  336.     mov    csectoff,ax
  337.     mov    ax,savcsectseg
  338.     mov    csectseg,ax
  339. ;
  340.     mov    ax,savabsreadoff
  341.     mov    absreadoff,ax
  342.     mov    ax,savabsreadseg
  343.     mov    absreadseg,ax
  344. ;
  345.     mov    ax,savabswriteoff
  346.     mov    abswriteoff,ax
  347.     mov    ax,savabswriteseg
  348.     mov    abswriteseg,ax
  349. ;
  350.     mov    ax,savkeepoff
  351.     mov    keepoff,ax
  352.     mov    ax,savkeepseg
  353.     mov    keepseg,ax
  354. ;
  355.     sti
  356. ;
  357.         pop     es
  358.     ret
  359. ;
  360.     assume    es:nothing
  361. ;
  362. _tsk_remove_dos    endp
  363. ;
  364. ;
  365. ;---------------------------------------------------------------------------
  366. ;
  367. ;    Stack-Offsets relative to BP
  368. ;
  369. caller_cs    =    4        ; Caller's CS
  370. caller_flags    =    6        ; Caller's Flags
  371. ;
  372. ;
  373. ;---------------------------------------------------------------------------
  374. ;
  375. ;    INT 25: Absolute Disk Read 
  376. ;
  377. ;    This interrupt is translated into INT 21, function C0.
  378. ;    This function is re-translated later after the necessary resources
  379. ;    have been requested.
  380. ;
  381. absread_int:
  382.     mov    ah,0c0h
  383.     jmp    short absrw_int
  384. ;
  385. ;
  386. ;---------------------------------------------------------------------------
  387. ;
  388. ;    INT 26: Absolute Disk Write
  389. ;
  390. ;    This interrupt is translated into INT 21, function C1.
  391. ;    This function is re-translated later after the necessary resources
  392. ;    have been requested.
  393. ;
  394. abswrite_int:
  395.     mov    ah,0c1h
  396. ;
  397. ;    Interrupts 25 und 26 leave the flag-word on the stack.
  398. ;    Since flags are removed in normal processing, the flag-word
  399. ;    has to be duplicated on the stack here.
  400. ;
  401. absrw_int:
  402.     push    bp            ; reserve space
  403.     push    bp            ; save BP
  404.     mov    bp,sp
  405.     sti
  406.     push    ax
  407.     mov    ax,4[bp]        ; Move return offset, segment down
  408.     mov    2[bp],ax
  409.     mov    ax,6[bp]
  410.     mov    4[bp],ax
  411.     mov    ax,8[bp]        ; duplicate flags
  412.     mov    6[bp],ax
  413.     pop    ax
  414.     push    caller_flags[bp]
  415.     jmp    short dosentry_2
  416. ;
  417. ;---------------------------------------------------------------------------
  418. ;
  419. ;    INT 27: Terminate But Stay Resident Interrupt
  420. ;
  421. ;    This interrupt is translated to INT 21, function 31.
  422. ;
  423. keep_int:
  424.     push    bp
  425.     mov    bp,sp
  426.     push    caller_flags[bp]    ; flags (bp-2)
  427.     sti                ; allow interrupts
  428. ;
  429.     add    dx,0fh            ; last addr + 0f to round
  430.     sub    dx,caller_cs[bp]    ; minus CS (= PSP)
  431.     mov    cl,4
  432.     shr    dx,cl            ; div 16 = paragraphs
  433.  
  434.     mov    ax,3100h        ; Keep process
  435.     jmp    short dosentry_2
  436. ;
  437. ;---------------------------------------------------------------------------
  438. ;
  439. ;    INT 20: Terminate Program interrupt
  440. ;
  441. ;    This interrupt is translated to INT 21, function 0.
  442. ;
  443. terminate_int:
  444.     mov    ah,0
  445. ;
  446. ;    fall through
  447. ;
  448. ;---------------------------------------------------------------------------
  449. ;
  450. ;    INT 21: DOS-Interrupt
  451. ;
  452. dosentry        proc    far
  453. ;
  454. ;    Save registers
  455. ;
  456.     push    bp
  457.     mov    bp,sp
  458.     push    caller_flags[bp]    ; flags (bp-2)
  459. ;
  460. dosentry_2:
  461.     push    es
  462.     push    ds
  463.     push    dx
  464.     push    cx
  465.     push    bx
  466.     push    ax
  467.     push    si
  468.     push    di
  469. ;
  470. ;    Here we check if the DOS critical region is active.
  471. ;    If yes, this means that some outside background process has
  472. ;    started DOS (most likely DOS PRINT).
  473. ;    To avoid busy waiting, we wait for the "critical" flag to be
  474. ;    cleared, if this is *not* the task that set the flag.
  475. ;    The task that set the critical task is *not* made waiting.
  476. ;
  477. wait_crit_loop:
  478.     cli
  479.     cmp    cs:critsect_active,0
  480.     je    no_crit
  481.     mov    ax,word ptr cs:crit_task
  482.     cmp    word ptr _tsk_current,ax
  483.     jne    wait_crit
  484.     mov    ax,word ptr cs:crit_task+2
  485.     cmp    word ptr _tsk_current+2,ax
  486.     je    no_crit
  487. ;
  488. wait_crit:
  489.     xor    ax,ax
  490.     push    ax
  491.     push    ax
  492.     mov    ax,offset critical
  493.     push    ds
  494.     push    ax
  495.     call    _wait_flag_clear
  496.     add    sp,8
  497. ;
  498. no_crit:
  499.     mov    cs:ctask_active,1    ; mark that we are active
  500.     sti                ; Interrupts allowed now
  501. ;
  502.     cld
  503.     mov    bx,SEG dgroup
  504.     mov    ds,bx
  505.     mov    es,bx
  506. ;
  507.         cmp     ah,4ch                  ; terminate?
  508.         jne     dosent_x
  509.         mov     ah,0                    ; translate to fn 0
  510. dosent_x:
  511.     cmp    ah,0ch
  512.     jbe    lower_funcs
  513.     jmp    upper_funcs
  514. ;
  515. ;    Functions 00-0C
  516. ;
  517. lower_funcs:
  518. ;
  519. ;    first, request the "lower_dos" resource
  520. ;
  521.     mov    bx,offset lower_dos
  522.     xor    cx,cx
  523.     push    cx        ; no timeout
  524.     push    cx
  525.     push    ds        ; resource address
  526.     push    bx
  527.     call    _request_resource
  528.     add    sp,8
  529. ;
  530. ;    we have it, now let's get the upper_dos resource, too
  531. ;
  532.     mov    bx,offset upper_dos
  533.     xor    cx,cx
  534.     push    cx        ; no timeout
  535.     push    cx
  536.     push    ds        ; resource address
  537.     push    bx
  538.     call    _request_resource
  539.     add    sp,8
  540. ;
  541. ;    both resources gained, now we may execute the function if dos is free
  542. ;
  543.     pop    di
  544.     pop    si
  545.     pop    ax
  546.     pop    bx
  547.     pop    cx
  548.     pop    dx
  549. ;
  550.     call    wait_dos_free
  551. ;
  552.     or    ah,ah            ; terminate ?
  553.     je    fg_terminate        ; special treatment required
  554.     pop     ds
  555.     pop    es
  556.     popf
  557.     pop    bp
  558. ;
  559.     dos                ; execute function
  560. ;
  561. ;    Now we have to release the resources.
  562. ;
  563.     pushf                ; save registers again
  564.     sti
  565.     push    es
  566.     push    ds
  567.     push    dx
  568.     push    cx
  569.     push    bx
  570.     push    ax
  571.     push    si
  572.     push    di
  573. ;
  574.     mov    bx,SEG dgroup
  575.     mov    ds,bx
  576.     mov    es,bx
  577. ;
  578.     mov    bx,offset upper_dos
  579.     push    ds        ; resource address
  580.     push    bx
  581.     call    _release_resource
  582.     add    sp,4
  583. ;
  584.     mov    bx,offset lower_dos
  585.     push    ds        ; resource address
  586.     push    bx
  587.     call    _release_resource
  588.     add    sp,4
  589. ;
  590. ;    If both resources are free now, clear the ctask_active flag to
  591. ;    allow other background processes to gain access to DOS.
  592. ;
  593.     cli
  594.     mov    ax,upper_dos.rstate
  595.         or    ax,ax
  596.         jz    no_relc
  597.     cmp    ax,lower_dos.rstate
  598.     jne    no_relc
  599.     mov    cs:ctask_active,0
  600. no_relc:
  601. ;
  602. ;    All done, restore registers and return.
  603. ;
  604.     pop    di
  605.     pop    si
  606.     pop    ax
  607.     pop    bx
  608.     pop    cx
  609.     pop    dx
  610.     pop     ds
  611.     pop    es
  612.     popf
  613. ;
  614.     ret    2            ; don't restore flags
  615. ;
  616. ;
  617. ;    The terminate request requires special treatment.
  618. ;    Since terminating the program without first un-installing
  619. ;    would crash the system, we do this here, not without telling
  620. ;    the user something went very wrong.
  621. ;
  622. fg_terminate:
  623.     cli
  624.     call    _remove_tasker
  625.     mov    dx,offset term_err_msg
  626.     mov    ah,9
  627.     int    21h
  628.     mov    ax,4cffh
  629.     int    21h
  630. ;
  631. ;--------------------------------------------------------------------------
  632. ;
  633. ;    Functions 0D and above
  634. ;
  635. upper_funcs:
  636.     mov    bx,offset upper_dos
  637.     xor    cx,cx
  638.     push    cx        ; no timeout
  639.     push    cx
  640.     push    ds        ; resource address
  641.     push    bx
  642.     call    _request_resource
  643.     add    sp,8
  644. ;
  645. ;    resource gained, now we may execute the function if dos is free
  646. ;
  647.     pop    di
  648.     pop    si
  649.     pop    ax
  650.     pop    bx
  651.     pop    cx
  652.     pop    dx
  653. ;
  654.     call    wait_dos_free
  655. ;
  656.     pop     ds
  657.     pop    es
  658. ;
  659. ;
  660. ;    Filter pseudo-functions C0/C1 (Absolute Read/Write)
  661. ;
  662.     cmp    ah,0c0h
  663.     jne    uf_exec1
  664.     popf
  665.     pop    bp
  666.     call    exec_absread
  667.     jmp    short uf_complete
  668. uf_exec1:
  669.     cmp    ah,0c1h
  670.     jne    uf_exec2
  671.     popf
  672.     pop    bp
  673.     call    exec_abswrite
  674.     jmp    short uf_complete
  675. ;
  676. uf_exec2:
  677.     popf
  678.     pop    bp
  679.     dos                ; execute function
  680. ;
  681. ;    Now we have to release the resources.
  682. ;
  683. uf_complete:
  684.     pushf                ; save registers again
  685.     sti
  686.     push    es
  687.     push    ds
  688.     push    dx
  689.     push    cx
  690.     push    bx
  691.     push    ax
  692.     push    si
  693.     push    di
  694. ;
  695.     mov    bx,SEG dgroup
  696.     mov    ds,bx
  697.     mov    es,bx
  698. ;
  699.     mov    bx,offset upper_dos
  700.     push    ds        ; resource address
  701.     push    bx
  702.     call    _release_resource
  703.     add    sp,4
  704. ;
  705. ;    If both resources are free now, clear the ctask_active flag to
  706. ;    allow other background processes to gain access to DOS.
  707. ;
  708.     cli
  709.     mov    ax,upper_dos.rstate
  710.         or    ax,ax
  711.         jz    no_relc1
  712.     cmp    ax,lower_dos.rstate
  713.     jne    no_relc1
  714.     mov    cs:ctask_active,0
  715. no_relc1:
  716. ;
  717. ;    All done, restore registers and return.
  718. ;
  719.     pop    di
  720.     pop    si
  721.     pop    ax
  722.     pop    bx
  723.     pop    cx
  724.     pop    dx
  725.     pop     ds
  726.     pop    es
  727.     popf
  728. ;
  729.     ret    2            ; don't restore flags
  730. ;
  731. ;
  732. dosentry    endp
  733. ;
  734. ;--------------------------------------------------------------------------
  735. ;
  736. ;    Absolute Read/Absolute Write.
  737. ;
  738. exec_absread    proc    near
  739.  
  740.     pushf
  741.     call    cs:savabsread
  742.     inc    sp            ; Remove flags (not using ADD,
  743.     inc    sp            ; this would clobber Carry)
  744.     ret
  745.  
  746. exec_absread    endp
  747. ;
  748. exec_abswrite    proc    near
  749.  
  750.     pushf
  751.     call    cs:savabswrite
  752.     inc    sp            ; Remove flags (not using ADD,
  753.     inc    sp            ; this would clobber Carry)
  754.     ret
  755.  
  756. exec_abswrite    endp
  757. ;
  758. ;----------------------------------------------------------------------------
  759. ;
  760. wait_dos_free    proc    near
  761. ;
  762.     push    es
  763.     push    bx
  764. in_use_loop:
  765.     cmp    idle_active,0        ; idle interrupt active?
  766.     jne    dos_free        ; then don't check for flag
  767. ;
  768.     les    bx,in_use
  769.     cmp    word ptr es:[bx],0
  770.     je    dos_free
  771.     cmp    dos310,0
  772.     jne    is_in_use
  773.     cmp    byte ptr es:[bx],0
  774.     je    dos_free
  775. is_in_use:
  776.     pushf
  777.     call    scheduler
  778.     jmp    in_use_loop
  779. ;
  780. dos_free:
  781.     pop    bx
  782.     pop    es
  783.     ret
  784. ;
  785. wait_dos_free    endp
  786. ;
  787. ;----------------------------------------------------------------------------
  788. ;
  789. ;    INT 28: DOS Idle Interrupt
  790. ;
  791. idleentry    proc    far
  792. ;
  793.     push    ds
  794.     push    es
  795.     push    ax
  796. ;
  797.     mov    ax,SEG dgroup
  798.     mov    ds,ax
  799.     mov    es,ax
  800. ;
  801. ;    Check if someone is waiting for upper_dos. If not, we can return
  802. ;    immediately.
  803. ;
  804.     mov    ax,word ptr upper_dos.rwaiting
  805.     or    ax,word ptr upper_dos.rwaiting+2
  806.     jz    idle_exit
  807. ;
  808. ;    Also make sure this is not a second invocation of INT 28.
  809. ;    Normally, this should never happen, but better safe than sorry.
  810. ;
  811.     cmp    idle_active,0
  812.     jne    idle_exit
  813.     inc    idle_active
  814. ;
  815. ;    someone is waiting, let's please him by releasing the resource
  816. ;
  817.     mov    idle_ss,ss        ; Switch to local stack
  818.     mov    idle_sp,sp
  819.     mov    ax,ds
  820.     mov    ss,ax
  821.     mov    sp,offset local_stack
  822. ;
  823.     sti                ; Interrupts allowed now
  824. ;
  825.         push    bx            ; save remaining regs
  826.     push    cx
  827.     push    dx
  828. ;
  829. ;    temporarily increase priority
  830. ;
  831.     les    bx,_tsk_current
  832.     push    es:prior[bx]
  833.     mov    es:prior[bx],0ffffh
  834.     push    bx
  835.     push    es
  836. ;
  837. ;    release resource & request it again
  838. ;
  839.     mov    ax,ds
  840.     mov    es,ax
  841.     mov    bx,offset upper_dos
  842.     push    ds
  843.     push    bx
  844.     call    _release_resource
  845.     add    sp,4
  846. ;
  847.     mov    bx,offset upper_dos
  848.     xor    cx,cx
  849.     push    cx
  850.     push    cx
  851.     push    ds
  852.     push    bx
  853.     call    _request_resource
  854.     add    sp,8
  855. ;
  856. ;    ready, restore priority, stack & regs
  857. ;
  858.     cli
  859.     pop    es
  860.     pop    bx
  861.     pop    es:prior[bx]
  862. ;
  863.     pop    dx
  864.     pop    cx
  865.     pop    bx
  866. ;
  867.     mov    ss,idle_ss        ; restore stack
  868.     mov    sp,idle_sp
  869. ;
  870.     mov    idle_active,0
  871. ;
  872. idle_exit:
  873.     pop    ax
  874.         pop     es
  875.     pop    ds
  876. ;
  877.     jmp    cs:savidle        ; chain to original interrupt
  878. ;
  879. idleentry    endp
  880. ;
  881. ;---------------------------------------------------------------------------
  882. ;
  883. ;    INT 2A: DOS Critical Section Interrupt.
  884. ;
  885. ;    Not documented.
  886. ;    Is used by DOS PRINT to mark Critical Regions.
  887. ;    Usage by PRINT:
  888. ;        AX = 8700 - Begin Critical Region
  889. ;                Returns:
  890. ;                Carry set if already active.
  891. ;        AX = 8701 - End Critical Region
  892. ;
  893. ;    Both these functions are handled here.
  894. ;
  895. ;    Other usage in DOS, function unknown:
  896. ;        AH = 82 (AL undefined)
  897. ;            seems to be called on DOS-Functions > 0C
  898. ;        AH = 84 (AL undefined)
  899. ;            seems to be called when DOS is idle
  900. ;
  901. ;    These functions are currently ignored.
  902. ;
  903. critsectint    proc    far
  904.  
  905.     cmp    ax,8700h    ; Enter critical region
  906.     jne    csi1
  907.     cmp    cs:critsect_active,0
  908.     stc
  909.     jnz    critsect_end
  910.     cmp    cs:ctask_active,0
  911.     stc
  912.     jnz    critsect_end
  913. ;
  914.     inc    cs:critsect_active
  915.     push    ax
  916.     push    bx
  917.     push    cx
  918.     push    dx
  919.     push    ds
  920.     push    es
  921.     mov    ax,seg dgroup
  922.     mov    ds,ax
  923.     mov    es,ax
  924.     mov    ax,word ptr _tsk_current
  925.     mov    word ptr cs:crit_task,ax
  926.     mov    ax,word ptr _tsk_current+2
  927.     mov    word ptr cs:crit_task+2,ax
  928.     mov    ax,offset critical
  929.     push    ds
  930.     push    ax
  931.     call    _set_flag
  932.     add    sp,4
  933.     pop    es
  934.     pop    ds
  935.     pop    dx
  936.     pop    cx
  937.     pop    bx
  938.     pop    ax
  939.     clc
  940. critsect_end:
  941.     ret    2
  942. ;
  943. csi1:
  944.     cmp    ax,8701h    ; Leave critical region
  945.     jne    csi2
  946.     mov    cs:critsect_active,0
  947.     push    ax
  948.     push    bx
  949.     push    cx
  950.     push    dx
  951.     push    ds
  952.     push    es
  953.     mov    ax,seg dgroup
  954.     mov    ds,ax
  955.     mov    es,ax
  956.     mov    ax,offset critical
  957.     push    ds
  958.     push    ax
  959.     call    _clear_flag
  960.     add    sp,4
  961.     pop    es
  962.     pop    ds
  963.     pop    dx
  964.     pop    cx
  965.     pop    bx
  966.     pop    ax
  967. csi2:
  968.     iret
  969. ;
  970. critsectint    endp
  971. ;
  972. ;
  973. ;---------------------------------------------------------------------------
  974. ;
  975.         end
  976.  
  977.