Subversion Repositories Kolibri OS

Rev

Rev 2 | Rev 4 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. label  next_usage_update   dword   at  0xB008
  2. label  timer_ticks         dword   at  0xFDF0
  3.  
  4. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  5. ;; IRQ0 HANDLER (TIMER INTERRUPT) ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. align 32
  9. irq0:
  10.  
  11.         cmp   [error_interrupt],-1
  12.         je    no_error_in_previous_process
  13.  
  14.         mov   edi,[error_interrupt]
  15.         shl   edi, 3
  16.         mov   [edi+tss0i_l +5], word 01010000b *256 +11101001b
  17.  
  18.         mov   edi,[error_interrupt]
  19.         shl   edi,7
  20.         add   edi,0x290000
  21.         mov   esi,[error_interrupt_entry]
  22.         mov   [edi+l.eip-tss_sceleton],esi
  23.         mov   [edi+l.eflags-tss_sceleton],dword 0x11002
  24.  
  25.         mov   [0xffff],byte 0
  26.  
  27.         mov   [error_interrupt],-1
  28.  
  29.      no_error_in_previous_process:
  30.  
  31.         mov   edi,[0x3000]
  32.         shl   edi, 3
  33.                          ; fields of TSS descriptor:
  34.         mov   [edi+gdts+ tss0 +5], word 01010000b *256 +11101001b
  35.  
  36.         inc   dword [timer_ticks]
  37.  
  38.         mov   eax, [timer_ticks]
  39. ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  40.         call  playNote           ; <<<--- INSERT THIS LINE !!!!!!!!!!
  41. ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  42.  
  43.         cmp   eax,[next_usage_update]
  44.         jb    .nocounter
  45.         add   eax,100
  46.         mov   [next_usage_update],eax
  47.         call  updatecputimes
  48.      .nocounter:
  49.  
  50.         mov   edi, [0x3010]
  51.  
  52.         mov   ebx, [edi+0x18] ; time stamp counter add
  53.         call  _rdtsc
  54.         sub   eax, ebx
  55.         add   eax, [edi+0x14] ; counter sum
  56.         mov   [edi+0x14], eax
  57.  
  58.         mov   ebx,[0x3000]
  59.  
  60.         cmp   [0xffff], byte 1   ;1
  61.         je   do_not_change_task ;je
  62.  
  63.       .waiting_for_termination:
  64.       .waiting_for_reuse:
  65.       .waiting_on_queue:
  66.         add   edi,0x20
  67.         inc   ebx
  68.  
  69.         mov   al, byte [edi+0xA]
  70.         cmp   al, 3
  71.         je    .waiting_for_termination
  72.         cmp   al, 4
  73.         je    .waiting_for_termination
  74.         cmp   al, 9
  75.         je    .waiting_for_reuse
  76.         cmp   al, 16
  77.         je    .waiting_on_queue
  78.         cmp   al, 17
  79.         je    .waiting_on_queue
  80.  
  81.         cmp   ebx,[0x3004]
  82.         jbe   nsched0
  83.         mov   ebx,1
  84.         mov   edi,0x3020
  85.  
  86.       nsched0:
  87.  
  88.         mov   [0x3000],ebx
  89.         mov   [0x3010],edi
  90.  
  91.       do_not_change_task:
  92.  
  93.         mov   edx,[0x3000]
  94.         lea   edx,[tss0sys+8*edx]
  95.         ;mov   [8*0x40+idts+8+0], word 0
  96.         ;mov   [8*0x40+idts+8+2],dx
  97.         ;mov   [8*0x40+idts+8+4],word 11100101b*256
  98.         ;mov   [8*0x40+idts+8+6], word 0
  99.  
  100.         call  _rdtsc
  101.         mov   [edi+0x18],eax
  102.  
  103.         cmp   [0xffff],byte 0
  104.         je    nodecffff
  105.         dec   byte [0xffff]
  106.       nodecffff:
  107.  
  108.  
  109.         shl   ebx, 3
  110.         xor   eax, eax
  111.         add   ebx, tss0
  112.         mov   word  [0xB004], bx   ; selector    ;mov   [tss_s],bx
  113.         mov   dword [0xB000], eax  ; offset
  114.  
  115.         mov   al,0x20   ; send End Of Interrupt signal
  116.         mov   dx,0x20
  117.         out   dx,al
  118. .switch:
  119.         jmp   pword [0xB000]
  120.         inc [context_counter] ;noname & halyavin
  121.         jmp   irq0
  122.  
  123. iglobal
  124. context_counter dd 0 ;noname & halyavin
  125. endg
  126.  
  127.  
  128. align 4
  129. change_task:
  130.  
  131.         mov   [0xffff],byte 2
  132.  
  133.         dec   dword [timer_ticks]  ; because irq0 will increase it
  134.  
  135.         int   0x20   ; irq0 handler
  136.  
  137.         ret
  138.  
  139.  
  140.  
  141. align 4
  142. updatecputimes:
  143.  
  144.         mov  eax,[idleuse]
  145.         mov  [idleusesec],eax
  146.         mov  [idleuse],dword 0
  147.         mov  ecx, [0x3004]
  148.         mov  edi, 0x3020
  149.       .newupdate:
  150.         mov  ebx,[edi+0x14]
  151.         mov  [edi+0x1c],ebx
  152.         mov  [edi+0x14],dword 0
  153.         add  edi,0x20
  154.         dec  ecx
  155.         jnz  .newupdate
  156.  
  157.         ret
  158.  
  159.  
  160.  
  161. ;
  162. ; Wait queue is 16 bytes
  163. ; dd return code                +12
  164. ; dd pointer to process         +8
  165. ; dd prev                       +4
  166. ; dd next                       +0
  167. ;
  168. ; eax - pointer to pointer to the wait queue
  169. ; return:
  170. ; ecx - return code
  171. sleep_on_queue:
  172.     sub esp,16          ; reserve space for wait node
  173.     mov ecx,esp         ; ecx=this_node, [eax]=queue
  174.  
  175.     pusha
  176.  
  177.     mov ebx,[0x3010]    ; get pointer to the current process
  178.     mov [ecx+8],ebx
  179.  
  180.     pushf
  181.     cli                 ; adding element to the wait queue must be atomic
  182.  
  183.     mov edi,[eax]       ; edi=queue
  184.     and edi,edi         ; check if queue is empty
  185.     jz .is_empty
  186.  
  187.     ; add element at the end of wait queue
  188.  
  189.     mov edx,[edi+4]     ; get pointer to prev edx=queue->prev
  190.     mov [ecx+4],edx     ; this_node->prev=queue->prev
  191.     mov [ecx+0],edi     ; this_node->next=queue
  192.     mov [edx+0],ecx     ; this_node->prev->next=this_node
  193.     mov [edi+4],ecx     ; queue->prev=this_node
  194.     jmp .added_ok
  195. .is_empty:
  196.     ; set this element as first in the queue
  197.     mov [ecx+0],ecx     ; this_node->next=this_node
  198.     mov [ecx+4],ecx     ; this_node->prev=this_node
  199.     mov [eax],ecx       ; [queue]=this_node
  200. .added_ok:
  201.  
  202.     popf                ; we can safely restore interrupts
  203.  
  204.     mov [ebx+0xa],byte 17 ; set current task state as sleeping
  205.     call change_task    ; schedule new thread
  206.  
  207.     ; someone has called wake_up_queue
  208.  
  209.     pushf               ; disable interrupts
  210.     cli
  211.  
  212.     mov edx,[ecx+0]     ; edx=this_node->next
  213.     mov esi,[ecx+4]     ; esi=this_node->prev
  214.  
  215.     ; check if we need to remove this node from head
  216.     cmp [eax],ecx
  217.     jne .no_head
  218.  
  219.     cmp [ecx+0],ecx ; check if queue is empty
  220.     jne .not_empty
  221.  
  222.     mov [eax],dword 0
  223.     jmp .no_head
  224.  
  225. .not_empty:
  226.     mov [eax],edx
  227.  
  228.     ; remove our node from the queue (this must be atomic)
  229. .no_head:
  230.     mov [edx+4],esi     ; this_node->next->prev=this_node->prev
  231.     mov [esi+0],edx     ; this_node->prev->next=this_node->next
  232.  
  233.     popf
  234.     popa
  235.     add esp,12
  236.     pop ecx
  237.     ret
  238.  
  239. ; eax - pointer to the wait queue
  240. ; ebx - wake up all (1=yes, 0=no)
  241. ; ecx - return code
  242. ; return:
  243. ; ebx - number of processes woken
  244. wake_up_queue:
  245.     and eax,eax
  246.     jnz .nz
  247.     ret
  248. .nz:
  249.     push eax
  250.     push ebx
  251.     push ecx
  252.     push edx
  253.     push esi
  254.  
  255.     pushf
  256.     cli
  257.  
  258.     xor ebx,ebx
  259.     mov edx,eax
  260. .wake_loop:
  261.  
  262.     mov [edx+12],ecx
  263.     mov esi,[edx+8]
  264.     mov byte [esi+0xa],0
  265.     inc ebx
  266.  
  267.     mov edx,[edx+0]
  268.     cmp edx,eax
  269.     jne .wake_loop
  270.  
  271.     and ebx,ebx
  272.     jz .wake_up_1
  273.  
  274. .return_it:
  275.     popf
  276.     pop esi
  277.     pop edx
  278.     pop ecx
  279.     add esp,4
  280.     pop eax
  281.     ret
  282. .wake_up_1:
  283.     mov [eax+12],ecx
  284.     mov ecx,[eax+8]
  285.     mov byte [ecx+0xa],0
  286.     jmp .return_it
  287.