Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1 ha 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
3 halyavin 96
        ;mov   [8*0x40+idts+8+2],dx
1 ha 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