home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1987 / 12 / holub / schedule.asm < prev    next >
Assembly Source File  |  1987-12-21  |  33KB  |  345 lines

  1.    PAGE   56,132                                                                              
  2.    TITLE  SPEEDUP.ASM: System-clock-modification routines                                     
  3. ;------------------------------------------------------------                                 
  4.                                                                                               
  5. DEBUG   equ 1   ; Set to 1 to make internal symbols public for                                
  6.                 ; debugging.                                                                  
  7.                                                                                               
  8. DOSPEED equ 1   ; Set to 0 to disable everything except                                       
  9.                 ; global-variable initialization in speedup.                                  
  10.                                                                                               
  11. ;------------------------------------------------------------                                 
  12. ; Public Subroutines are:                                                                     
  13. ;                                                                                             
  14. ; t_cli()                                                                                     
  15. ;       Disable Interrupts                                                                    
  16. ; t_sti()                                                                                     
  17. ;       Enable Interrupts                                                                     
  18. ;                                                                                             
  19. ;------------------------------------------------------------                                 
  20. ; _t_speedup( factor )                                                                        
  21. ; int factor;                                                                                 
  22. ;                                                                                             
  23. ;       Speed up the system clock by the indicated factor                                     
  24. ;       (1, 2, 3, 4, etc.).  Call the scheduler                                               
  25. ;       on every timer interrupt and call the default clock                                   
  26. ;       routine as well every "factor" ticks. For example,                                    
  27. ;       speedup( 2 ) speeds up the system clock by                                            
  28. ;       a factor of two; the normal interrupt-service                                         
  29. ;       routine that's used by DOS will be called every-                                      
  30. ;       other tick. A speedup factor of 1 or 0 doesn't modify                                 
  31. ;       the clock rate.                                                                       
  32. ;                                                                                             
  33. ; _t_slowdown()                                                                               
  34. ;                                                                                             
  35. ;       Restore the clock to the normal speed and disconnect                                  
  36. ;       the routine installed with a previous speedup() call                                  
  37. ;       (if one is installed).                                                                
  38. ;------------------------------------------------------------                                 
  39. ;                                                                                             
  40. ; t_block()                                                                                   
  41. ; t_release()                                                                                 
  42. ;                                                                                             
  43. ;   Disable the scheduler but not the normal clock interrupt.                                 
  44. ;   The default system interrupt-service routine is processed                                 
  45. ;   in the normal way, on every Nth clock tick. Use these                                     
  46. ;   routines carefully. If they're used in a tight loop, it's                                 
  47. ;   possible that ALL timer interrupts will be ignored, even                                  
  48. ;   if the processor is released for a while inside the loop.                                 
  49. ;   In this situation sti() and cli() are better.                                             
  50. ;                                                                                             
  51. ;------------------------------------------------------------                                 
  52. ; long numint();          Number of unblocked interrupts.                                     
  53. ; long numblk();          Number of blocked interrupts.                                       
  54. ;                                                                                             
  55.                                                                                               
  56. _TEXT   SEGMENT  BYTE PUBLIC 'CODE'                                                           
  57. _TEXT   ENDS                                                                                  
  58. _DATA   SEGMENT  WORD PUBLIC 'DATA'                                                           
  59. _DATA   ENDS                                                                                  
  60. CONST   SEGMENT  WORD PUBLIC 'CONST'                                                          
  61. CONST   ENDS                                                                                  
  62. _BSS    SEGMENT  WORD PUBLIC 'BSS'                                                            
  63. _BSS    ENDS                                                                                  
  64. DGROUP  GROUP   CONST,  _BSS,   _DATA                                                         
  65.         ASSUME  CS: _TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP                                 
  66.                                                                                               
  67. EXTRN   __chkstk:NEAR                                                                         
  68. EXTRN   __t_reschedule:NEAR                                                                   
  69. EXTRN   _T_active:WORD                                                                        
  70.                                                                                               
  71. ;------------------------------------------------------------                                 
  72.                                                                                               
  73. TIMR_CTRL   = 43H       ; address of timer control port                                       
  74. TIMR_0_DATA = 40H       ; address of counter 0 data port                                      
  75. TIMR_0_LOAD = 36H       ; control word for timer                                              
  76.                                                                                               
  77. STKSIZE = 256           ; Number of bytes on interrupt-                                       
  78.                         ; service-routine stack                                               
  79.                                                                                               
  80. ;------------------------------------------------------------                                 
  81.                                                                                               
  82. _TEXT     SEGMENT                                                                             
  83.                                                                                               
  84. ;------------------------------------------------------------                                 
  85. ; Misc. variables. Note that I'm putting all these in the                                     
  86. ; code (_TEXT) segment so that I can find them when an                                        
  87. ; interrupt comes along. The PUBLIC statements are just for                                   
  88. ; debugging.                                                                                  
  89.                                                                                               
  90. old_int    equ  $                                                                             
  91. old_off    dw   ?       ; Offset of old timer interrupt routine.                              
  92. old_seg    dw   ?       ; Segment address of same.                                            
  93.                                                                                               
  94. tick_reset dw   ?                                                                             
  95. numticks   dw   ?       ; Initialized to tick_reset, decre-                                   
  96.                         ; mented on each timer interrupt,                                     
  97.                         ; reset to the speedup factor (and the                                
  98.                         ; old service routine is called) when                                 
  99.                         ; it reaches zero.                                                    
  100.                                                                                               
  101. stack  db  STKSIZE dup (0) ; Local stack for service routine                                  
  102.                            ; 30 bytes are used by real service                                
  103.                            ; routine, the rest is available                                   
  104.                            ; for the user service routine.                                    
  105. stack_end   dw  ?                                                                             
  106.                                                                                               
  107. old_ds      dw  ?                                                                             
  108. old_sp      dw  ?                                                                             
  109. old_ss      dw  ?                                                                             
  110. old_ax      dw  ?                                                                             
  111. old_ip      dw  ?                                                                             
  112. old_cs      dw  ?                                                                             
  113. old_fl      dw  ?                                                                             
  114.                                                                                               
  115. numint      dd 0        ; total number of interrupts                                          
  116. numblk      dd 0        ; number of times user routine blocked                                
  117.                                                                                               
  118. blocked     db  0       ; don't execute user routine if true                                  
  119.                                                                                               
  120. IF DEBUG                                                                                      
  121.     PUBLIC  old_int, old_off, old_seg, old_ds,                                                
  122.     PUBLIC  tick_reset, numticks, stack, stack_end, old_sp,                                   
  123.     PUBLIC  old_ss, old_ax, old_ip, old_cs, old_fl                                            
  124.     PUBLIC  blocked, serv, numint, numblk                                                     
  125. ENDIF                                                                                         
  126.                                                                                               
  127. ;------------------------------------------------------------                                 
  128. ; statistics stuff.                                                                           
  129. ;                                                                                             
  130. PUBLIC _t_numint, _t_numblk                                                                   
  131.                                                                                               
  132. _t_numint PROC NEAR                                                                           
  133.         mov     ax,WORD PTR cs:numint                                                         
  134.         mov     dx,WORD PTR cs:numint+2                                                       
  135.         ret                                                                                   
  136. _t_numint ENDP                                                                                
  137.                                                                                               
  138. _t_numblk PROC NEAR                                                                           
  139.         mov     ax,WORD PTR cs:numblk                                                         
  140.         mov     dx,WORD PTR cs:numblk+2                                                       
  141.         ret                                                                                   
  142. _t_numblk ENDP                                                                                
  143.                                                                                               
  144. ;------------------------------------------------------------                                 
  145. ; t_cli();  t_sti();  Disable and enable interrupts.                                          
  146. ;                                                                                             
  147. PUBLIC  _t_cli, _t_sti                                                                        
  148.                                                                                               
  149. _t_cli  PROC NEAR                                                                             
  150.         cli                                                                                   
  151.         ret                                                                                   
  152. _t_cli  ENDP                                                                                  
  153.                                                                                               
  154. _t_sti  PROC NEAR                                                                             
  155.         sti                                                                                   
  156.         ret                                                                                   
  157. _t_sti  ENDP                                                                                  
  158.                                                                                               
  159.                                                                                               
  160. ;------------------------------------------------------------                                 
  161. ; t_block();    Disable and enable user interrupt service                                     
  162. ; t_release();  routine but not the real interrupt service                                    
  163. ;               routine (or the interrupt itself).                                            
  164.                                                                                               
  165. PUBLIC  _t_block, _t_release                                                                  
  166.                                                                                               
  167. _t_block PROC NEAR                                                                            
  168.          mov  byte ptr cs:blocked,1                                                           
  169.          ret                                                                                  
  170. _t_block ENDP                                                                                 
  171.                                                                                               
  172. _t_release PROC NEAR                                                                          
  173.          mov  byte ptr cs:blocked,0                                                           
  174.          ret                                                                                  
  175. _t_release ENDP                                                                               
  176.                                                                                               
  177. ;------------------------------------------------------------                                 
  178. ; _t_speedup( factor )                                                                        
  179. ; int factor;                                                                                 
  180. ;                                       factor  = [bp+4]                                      
  181. ;                                       routine = [bp+6]                                      
  182. PUBLIC  __t_speedup                                                                           
  183.                                                                                               
  184. __t_speedup     PROC NEAR                                                                     
  185.                                                                                               
  186.         push    bp                                                                            
  187.         mov     bp,sp                                                                         
  188.         xor     ax,ax                                                                         
  189.         call    __chkstk                                                                      
  190.                                                                                               
  191.         mov     _TEXT:old_ds,ds     ; remember current DS.                                    
  192.         mov     ax,[bp+4]           ; AX         = factor                                     
  193.         mov     _TEXT:tick_reset,ax ; tick_reset = factor;                                    
  194.         mov     _TEXT:numticks,ax   ; numticks   = factor;                                    
  195.                                                                                               
  196. if DOSPEED                                                                                    
  197.                                                                                               
  198.         mov     ax,[bp+4]           ; if( factor && factor != 1)                              
  199.         cmp     ax,01H              ; {                                                       
  200.         je      noload              ;                                                         
  201.         cmp     ax,00H              ;                                                         
  202.         je      noload              ;                                                         
  203.                                     ;                                                         
  204.         mov     al,TIMR_0_LOAD      ;     Set up timer for load                               
  205.         out     TIMR_CTRL,al        ;                                                         
  206.         mov     ax,00000H           ;     Number of ticks                                     
  207.         mov     dx,00001H           ;             = 65536/factor                              
  208.         mov     bx,[bp+4]           ;     BX = factor.                                        
  209.         div     bx                  ;     AX = number of ticks                                
  210.         cli                         ;                                                         
  211.         out     TIMR_0_DATA,al      ;     Send new count to timer                             
  212.         mov     al,ah               ;                                                         
  213.         out     TIMR_0_DATA,al      ;                                                         
  214.         sti                         ; }                                                       
  215. noload:                                                                                       
  216.                                     ; Get the old vector                                      
  217.         mov     ah,35H              ;                                                         
  218.         mov     al,08H              ;                                                         
  219.         int     21H                 ;                                                         
  220.         mov     _TEXT:old_off,bx    ;                                                         
  221.         mov     _TEXT:old_seg,es    ;                                                         
  222.                                                                                               
  223.                                       ; set up the new vector                                 
  224.         mov     ah,25H                ;                                                       
  225.         mov     al,08H                ;                                                       
  226.         mov     dx,OFFSET _TEXT: serv ;                                                       
  227.         push    ds                    ;                                                       
  228.         push    cs                    ;                                                       
  229.         pop     ds                    ;                                                       
  230.         int     21H                   ;                                                       
  231.         pop     ds                    ;                                                       
  232. endif                                                                                         
  233.         mov     sp,bp                                                                         
  234.         pop     bp                                                                            
  235.         ret                                                                                   
  236.                                                                                               
  237. __t_speedup     ENDP                                                                          
  238.                                                                                               
  239. ;------------------------------------------------------------                                 
  240.                                                                                               
  241. PUBLIC  __t_slowdown                                                                          
  242.                                                                                               
  243. __t_slowdown    PROC NEAR                                                                     
  244.                                                                                               
  245.         push    bp                                                                            
  246.         mov     bp,sp                                                                         
  247.         xor     ax,ax                                                                         
  248.         call    __chkstk                                                                      
  249.                                                                                               
  250.         mov     ax,_TEXT:old_off ; See if the interrupts have                                 
  251.         or      ax,ax            ;                 changed.                                   
  252.         jz      no_int           ; No, don't fix them then                                    
  253.                                                                                               
  254.                                  ; restore old timer interrupt                                
  255.         push    ds               ;                                                            
  256.         mov     ah,25H           ;                                                            
  257.         mov     al,08H           ;                                                            
  258.         mov     ds,_TEXT:old_seg ;                                                            
  259.         mov     dx,_TEXT:old_off ;                                                            
  260.         int     21H              ;                                                            
  261.         pop     ds               ;                                                            
  262.                                                                                               
  263. no_int:                                                                                       
  264.         mov  al,TIMR_0_LOAD      ; Restore default system                                     
  265.         out  TIMR_CTRL,al        ; clock tick rate                                            
  266.         mov  al,0                                                                             
  267.         out  TIMR_0_DATA,al                                                                   
  268.         out  TIMR_0_DATA,al                                                                   
  269.                                                                                               
  270.         mov     sp,bp                                                                         
  271.         pop     bp                                                                            
  272.         ret                                                                                   
  273.                                                                                               
  274. __t_slowdown    ENDP                                                                          
  275.                                                                                               
  276. ;------------------------------------------------------------                                 
  277. ; Actual interrupt service routine.                                                           
  278. ; Note that the flags, cs, and ip are pushed on entry (because                                
  279. ; if the interrupt)                                                                           
  280. ;                                                                                             
  281. serv    PROC    NEAR                                                                          
  282.                                                                                               
  283.         push    ax                                                                            
  284.                                                                                               
  285.         mov     al, byte ptr cs:blocked ; If( servicing blocked)                              
  286.         or      al,al                   ; {                                                   
  287.         jz      serv1                   ;                                                     
  288.                                         ;                                                     
  289.         add     WORD PTR cs:numblk,1    ;    ++numblk;                                        
  290.         adc     WORD PTR cs:numblk+2,0  ;                                                     
  291.         jmp     servexit                ; }                                                   
  292. serv1:                                  ; else                                                
  293.         add     WORD PTR cs:numint,1    ; {                                                   
  294.         adc     WORD PTR cs:numint+2,0  ;    +numint;                                         
  295.         push    bx                      ;                                                     
  296.         push    cx                      ;    Save rest of                                     
  297.         push    dx                      ;        current context                              
  298.         push    si                                                                            
  299.         push    di                                                                            
  300.         push    bp                                                                            
  301.         push    ds                                                                            
  302.         push    es                                                                            
  303.                                                                                               
  304.         mov     ds,_TEXT:old_ds         ;    Restore Data segment                             
  305.         mov     bx,_T_active            ;    BX = T_active                                    
  306.         mov     [bx],sp                 ;    T_active->sp = SP                                
  307.         mov     [bx+2],ss               ;    T_active->ss = SS                                
  308.                                                                                               
  309.         push    cs                      ;    Set up local stack                               
  310.         pop     ss                      ;                                                     
  311.         mov     sp,offset _TEXT: stack_end ;                                                  
  312.                                                                                               
  313.         call    __t_reschedule          ;   in task.c                                         
  314.                                                                                               
  315.         mov     bx,_T_active            ;   BX = new T_active,                                
  316.         mov     ss,[bx+2]               ;   will be the same as                               
  317.         mov     sp,[bx]                 ;   the old T_active if                               
  318.         pop     es                      ;   no change is reqd.                                
  319.         pop     ds                      ;                                                     
  320.         pop     bp                      ;                                                     
  321.         pop     di                      ;                                                     
  322.         pop     si                      ;                                                     
  323.         pop     dx                      ;                                                     
  324.         pop     cx                      ;                                                     
  325.         pop     bx                      ;                                                     
  326.                                         ;                                                     
  327. servexit:                               ; }                                                   
  328.         dec     _TEXT:numticks          ; if(--numticks > 0)                                  
  329.         jle     serv3                   ; {                                                   
  330.         mov     al,20h                  ;    send EOI                                         
  331.         out     20h,al                  ;                                                     
  332.         pop     ax                                                                            
  333.         iret                            ; }                                                   
  334.                                         ; else                                                
  335. serv3:                                  ; {                                                   
  336.         mov     ax,_TEXT:tick_reset     ;    numticks = tick_reset;                           
  337.         mov     _TEXT:numticks,ax       ;                                                     
  338.         pop     ax                      ;                                                     
  339.         jmp     dword ptr _TEXT:old_int ;    jmp to old vector                                
  340.                                         ; }                                                   
  341. serv    ENDP                                                                                  
  342.                                                                                               
  343.                                                                                               
  344. _TEXT   ENDS                                                                                  
  345. END