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

  1. ; SWAP.ASM      Routine to do context swaps. Everything in                                    
  2. ;               this file is VERY compiler dependant and                                      
  3. ;               VERY nonportable.                                                             
  4. ;                                                                                             
  5.         TITLE   swap.c                                                                        
  6.         NAME    swap                                                                          
  7.                                                                                               
  8. _TEXT   SEGMENT  WORD PUBLIC 'CODE'                                                           
  9. _TEXT   ENDS                                                                                  
  10. _DATA   SEGMENT  WORD PUBLIC 'DATA'                                                           
  11. _DATA   ENDS                                                                                  
  12. CONST   SEGMENT  WORD PUBLIC 'CONST'                                                          
  13. CONST   ENDS                                                                                  
  14. _BSS    SEGMENT  WORD PUBLIC 'BSS'                                                            
  15.                                                                                               
  16. op      db       0      ; Used by rst_chkstk and chg_chkstk                                   
  17. segm    dw       0      ; (below).                                                            
  18. off     dw       0                                                                            
  19.                                                                                               
  20. save_bx dw       0      ; used by __t_swap_in                                                 
  21.                                                                                               
  22. _BSS    ENDS                                                                                  
  23. DGROUP  GROUP   CONST, _BSS, _DATA                                                            
  24.         ASSUME  CS: _TEXT, DS: DGROUP, SS: DGROUP                                             
  25.                                                                                               
  26. _DATA      SEGMENT                                                                            
  27. _DATA      ENDS                                                                               
  28.                                                                                               
  29. IF 1                                                                                          
  30. PUBLIC stack_err, mychkstk, rst_chkstk, chg_chkstk                                            
  31. PUBLIC op, segm, off                                                                          
  32. ENDIF                                                                                         
  33.                                                                                               
  34. ;------------------------------------------------------------                                 
  35. _TEXT      SEGMENT                                                                            
  36.                                                                                               
  37.         ASSUME  CS: _TEXT                                                                     
  38.                                                                                               
  39. PUBLIC  __t_swap_in     ; Swaps two tasks                                                     
  40. PUBLIC  __t_install     ; Installs a task when none active                                    
  41. PUBLIC  __t_shazam      ; Starts multitasking                                                 
  42. PUBLIC  _t_stop         ; Stops  multitasking.                                                
  43. PUBLIC  __t_sus_chkstk  ; Temporarily suspend stack checking.                                 
  44. PUBLIC  __t_rst_chkstk  ; Restore it again.                                                   
  45.                                                                                               
  46. EXTRN   __chkstk:NEAR   ; in standard library                                                 
  47. EXTRN   _free:NEAR      ; In standard library                                                 
  48. EXTRN   __t_slowdown:NEAR; In schedule.asm                                                    
  49. EXTRN   _t_block:NEAR   ; "                                                                   
  50. EXTRN   _t_release:NEAR ; "                                                                   
  51. EXTRN   _t_iserr:NEAR   ; In task.c                                                           
  52. EXTRN   _T_active:WORD  ; Declared in kernel.h. Pointer                                       
  53.                         ; to currently active task                                            
  54.                                                                                               
  55. ;------------------------------------------------------------                                 
  56.                                                                                               
  57. save_sp dw 0                                                                                  
  58. save_ss dw 0                                                                                  
  59. chk_on  dw 0            ; No stack probes while nonzero                                       
  60.                                                                                               
  61. ;------------------------------------------------------------                                 
  62.                                                                                               
  63. __t_shazam PROC NEAR                                                                          
  64.                                                                                               
  65.     ; Start the ball rolling. Save the current context.                                       
  66.     ; then start up the first task. On entry,                                                 
  67.     ; T_active must point at the first task to activate.                                      
  68.     ; Stack on entry (from top to bottom) is:                                                 
  69.     ;                                                                                         
  70.     ;  return address from _t_shazam call                                                     
  71.     ;  old bp saved by t_start                                                                
  72.     ;  t_start's return address                                                               
  73.     ;  speedup_factor passed to t_start                                                       
  74.     ;                                                                                         
  75.                                                                                               
  76.     add sp,2            ; Discard return addr to _t_shazam                                    
  77.                         ; Uncovering bp from main that                                        
  78.                         ; was saved by t_start()                                              
  79.     push si                                                                                   
  80.     push di                                                                                   
  81.     push ds             ; push this last                                                      
  82.                                                                                               
  83.     mov  WORD PTR cs:save_sp, sp                                                              
  84.     mov  WORD PTR cs:save_ss, ss                                                              
  85.                                                                                               
  86.     call chg_chkstk                                                                           
  87.     mov  bx, WORD PTR _T_active                                                               
  88.     jmp  shazam                                                                               
  89.                                                                                               
  90. __t_shazam ENDP                                                                               
  91.                                                                                               
  92. ;------------------------------------------------------------                                 
  93.                                                                                               
  94. _t_stop PROC NEAR                                                                             
  95.                                                                                               
  96.     ; t_stop( errcode )                                                                       
  97.     ;                                                                                         
  98.     ; This routine deletes the current task, causes                                           
  99.     ; multitasking to be turned off, and passes control                                       
  100.     ; back to the routine that called t_start()                                               
  101.     ; (immediately following the t_start call).                                               
  102.     ; Errcode is passed back to the calling routine as the                                    
  103.     ; return value of t_start().                                                              
  104.     ;                                                                                         
  105.     ; It can be called directly by a running task; it's                                       
  106.     ; called automatically when the last task is deleted,                                     
  107.     ; or when the only running task deletes itself.                                           
  108.                                                                                               
  109.     cli                         ; Just to make sure                                           
  110.                                                                                               
  111.     add sp,2                    ; Discard return address                                      
  112.     pop ax                      ; return value = errcode                                      
  113.                                                                                               
  114.     mov ss, WORD PTR cs:save_ss ; Restore initial stack...                                    
  115.     mov sp, WORD PTR cs:save_sp ;                                                             
  116.     pop ds                      ; ...and data segment.                                        
  117.                                                                                               
  118.     push  ax                                                                                  
  119.     call  rst_chkstk            ; Put back original __chkstk                                  
  120.     call  __t_slowdown          ; Disable weird timer int.                                    
  121.                                                                                               
  122.     pop   ax                    ; get back return value                                       
  123.     push  ax                                                                                  
  124.                                                                                               
  125.     or    ax,ax                 ; if( errcode == NOERR ) )                                    
  126.     jnz   t_stop1               ; {                                                           
  127.     push  _T_active             ;       free( T_active );                                     
  128.     call  _free                 ;                                                             
  129.     add   sp,2                  ; }                                                           
  130.                                                                                               
  131. t_stop1:                                                                                      
  132.     pop   ax                    ; return( errcode )                                           
  133.                                                                                               
  134.     pop   di                    ; resore si and di saved by                                   
  135.     pop   si                    ; by __t_shazem,                                              
  136.     pop   bp                    ; and bp saved by t_start.                                    
  137.     ret                         ;                                                             
  138. _t_stop ENDP                                                                                  
  139.                                                                                               
  140. ;------------------------------------------------------------                                 
  141.                                                                                               
  142. __t_install PROC NEAR                                                                         
  143.                                                                                               
  144.     ; _t_install(new)                                                                         
  145.     ; TCB       *new;                                                                         
  146.     ;                                                                                         
  147.     ;  Delete the current task and replace it with the                                        
  148.     ;  new one. This routine saves some space (and execution                                  
  149.     ;  time) by jumping into the middle of swap() to install                                  
  150.     ;  the new task. The scheduler must be blocked when                                       
  151.     ;  this routine is called. This routine does not                                          
  152.     ;  return.                                                                                
  153.                                                                                               
  154.     add   sp,2                  ; discard return address                                      
  155.     pop   bx                    ; bx = new                                                    
  156.                                                                                               
  157.     mov   ss,WORD PTR [bx+2]    ; ss:sp = new task's stack;                                   
  158.     mov   sp,WORD PTR [bx]                                                                    
  159.                                                                                               
  160.     push  bx                                                                                  
  161.     push  _T_active             ; free( T_active )                                            
  162.     call  _free                                                                               
  163.     add   sp,2                  ; Discard arg to free()                                       
  164.     pop   bx;                   ; get back bx.                                                
  165.                                                                                               
  166.     jmp   shazam                                                                              
  167.                                                                                               
  168. __t_install ENDP                                                                              
  169.                                                                                               
  170. ;------------------------------------------------------------                                 
  171.                                                                                               
  172. __t_swap_in PROC NEAR                                                                         
  173.                                                                                               
  174.     ; _t_swap_in( new )                                                                       
  175.     ; TCB *new;                                                                               
  176.     ;                                                                                         
  177.     ; Do a context swap. Replace T_active with new, This                                      
  178.     ; routine returns only when the original context is                                       
  179.     ; restored. Swapping MUST be blocked when this subroutine                                 
  180.     ; is called. Release() is called once the new context                                     
  181.     ; is installed and T_active is modified to point at the                                   
  182.     ; new task.                                                                               
  183.                                                                                               
  184.     cli                                                                                       
  185.     mov   WORD PTR cs:save_bx,bx                                                              
  186.     pop   bx            ; bx = return address                                                 
  187.     pushf               ; Save current context                                                
  188.     push  cs                                                                                  
  189.     push  bx            ;    (Push return address as new ip)                                  
  190.     push  ax                                                                                  
  191.     push  save_bx                                                                             
  192.     push  cx                                                                                  
  193.     push  dx                                                                                  
  194.     push  si                                                                                  
  195.     push  di                                                                                  
  196.     push  bp                                                                                  
  197.     push  ds                                                                                  
  198.     push  es                                                                                  
  199.                                                                                               
  200.     ; Stack now looks like this:                                                              
  201.     ;                                                                                         
  202.     ;   new     [sp + 24]                                                                     
  203.     ;   flags   [sp + 22]                                                                     
  204.     ;   cs      [sp + 20]                                                                     
  205.     ;   ip      [sp + 18]                                                                     
  206.     ;   ax      [sp + 16]                                                                     
  207.     ;   bx      [sp + 14]                                                                     
  208.     ;   cx      [sp + 12]                                                                     
  209.     ;   dx      [sp + 10]                                                                     
  210.     ;   si      [sp + 8]                                                                      
  211.     ;   di      [sp + 6]                                                                      
  212.     ;   bp      [sp + 4]                                                                      
  213.     ;   ds      [sp + 2]                                                                      
  214.     ;   es      [sp]            (top of stack)                                                
  215.                                                                                               
  216.     mov   bx,WORD PTR _T_active                                                               
  217.     mov   WORD PTR [bx+2],ss                                                                  
  218.     mov   WORD PTR [bx],sp                                                                    
  219.                                                                                               
  220.     mov   bx,sp                                                                               
  221.     mov   bx,WORD PTR [bx+24]   ; bx = new                                                    
  222.                                                                                               
  223. shazam:                         ; __t_shazam and __t_install                                  
  224.                                 ; come here to do the swap                                    
  225.                                                                                               
  226.     mov   WORD PTR _T_active,bx ; T_active = new;                                             
  227.     mov   ss,WORD PTR [bx+2]    ; Switch to new task's stack                                  
  228.     mov   sp,WORD PTR [bx]                                                                    
  229.                                                                                               
  230.     pop es                                                                                    
  231.     pop ds                                                                                    
  232.     pop bp                                                                                    
  233.     pop di                                                                                    
  234.     pop si                                                                                    
  235.     pop dx                                                                                    
  236.     pop cx                                                                                    
  237.     pop bx                                                                                    
  238.     pop ax                                                                                    
  239.                                                                                               
  240.     call _t_release                                                                           
  241.     sti                                                                                       
  242.     iret                                                                                      
  243.                                                                                               
  244. __t_swap_in ENDP                                                                              
  245.                                                                                               
  246.                                                                                               
  247. ;------------------------------------------------------------                                 
  248. ; __t_chg_chkstk()              Normal stack checking off                                     
  249. ; __t_rst_chkstk()              back on again                                                 
  250. ;                                                                                             
  251. ; __t_sus_chkstk()              Suspend stack checking temporarily                            
  252. ; __t_rst_chkstk()              restore it again.                                             
  253. ;                                                                                             
  254. ; Turn off Microsoft stack checking by overwriting the first                                  
  255. ; 5 bytes of __chkstk with an absolute jump to mychkstk.                                      
  256. ; This is a kludge but I can't get the Microsoft compiler                                     
  257. ; to link my own version of __chkstk, even when I use the                                     
  258. ; source file that they supply.                                                               
  259.                                                                                               
  260. chg_chkstk PROC NEAR                                                                          
  261.                                                                                               
  262.     mov bx,OFFSET __chkstk                                                                    
  263.                                                                                               
  264.     mov ah,BYTE PTR cs:[bx+0]                                                                 
  265.     mov BYTE PTR op,ah                                                                        
  266.                                                                                               
  267.     mov ax,WORD PTR cs:[bx+1]                                                                 
  268.     mov WORD PTR off,ax                                                                       
  269.                                                                                               
  270.     mov ax,WORD PTR cs:[bx+3]                                                                 
  271.     mov WORD PTR segm,ax                                                                      
  272.     mov BYTE PTR cs:[bx+0],0EAH                 ; EA=JMP                                      
  273.     mov WORD PTR cs:[bx+1],OFFSET mychkstk      ; offset                                      
  274.     mov WORD PTR cs:[bx+3],cs                   ; segment                                     
  275.                                                                                               
  276.     mov cs:chk_on,1                     ; Enable stack checking                               
  277.     ret                                                                                       
  278.                                                                                               
  279. chg_chkstk ENDP                                                                               
  280.                                                                                               
  281. rst_chkstk PROC NEAR                                                                          
  282.                                                                                               
  283.     mov bx,OFFSET __chkstk                                                                    
  284.                                                                                               
  285.     mov ah,BYTE PTR op                                                                        
  286.     mov BYTE PTR cs:[bx+0],ah                                                                 
  287.                                                                                               
  288.     mov ax,WORD PTR off                                                                       
  289.     mov WORD PTR cs:[bx+1],ax                                                                 
  290.                                                                                               
  291.     mov ax,WORD PTR segm                                                                      
  292.     mov WORD PTR cs:[bx+3],ax                                                                 
  293.     ret                                                                                       
  294.                                                                                               
  295. rst_chkstk ENDP                                                                               
  296.                                                                                               
  297. __t_sus_chkstk PROC NEAR                                                                      
  298.     mov cs:chk_on,0                                                                           
  299.     ret                                                                                       
  300. __t_sus_chkstk ENDP                                                                           
  301.                                                                                               
  302. __t_rst_chkstk PROC NEAR                                                                      
  303.     mov cs:chk_on,1                                                                           
  304.     ret                                                                                       
  305. __t_rst_chkstk ENDP                                                                           
  306.                                                                                               
  307. ;------------------------------------------------------------                                 
  308. ; On entry AX holds the number of bytes required for local                                    
  309. ; variables. Chkstk normally checks the stack and, at the                                     
  310. ; same time, finishes setting up the stack frame by                                           
  311. ; subtracting the contents of ax from the stack pointer.                                      
  312. ;                                                                                             
  313.                                                                                               
  314. mychkstk PROC   NEAR                                                                          
  315.                                                                                               
  316.     mov cx,cs:chk_on    ; If stack checking disabled at                                       
  317.     or  cx,cx           ; run time, skip past the actual                                      
  318.     jz  nocheck         ; test.                                                               
  319.                                                                                               
  320.     mov cx,_T_active                                                                          
  321.     add cx,44           ; Offset to stack base + 4                                            
  322.     cmp sp,cx           ; if( sp <= stack_base )                                              
  323.     jbe stack_err                                                                             
  324.                                                                                               
  325. nocheck:                                                                                      
  326.     pop cx              ; cx = return address                                                 
  327.     sub sp,ax           ; finish setting up stack frame                                       
  328.     jmp cx              ; ret to caller w/o modifying stack.                                  
  329.                                                                                               
  330. stack_err:              ; Return address still on the stack                                   
  331.     mov  ax,-9                                                                                
  332.     push ax                                                                                   
  333.     call _t_stop        ; Shouldn't return                                                    
  334.                                                                                               
  335.     mov cx,0                                                                                  
  336.     jmp cx              ; Panic abort to DOS                                                  
  337.                                                                                               
  338. mychkstk ENDP                                                                                 
  339.                                                                                               
  340. _TEXT   ENDS                                                                                  
  341. END