Subversion Repositories Kolibri OS

Rev

Rev 2381 | Rev 3504 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2381 Rev 2455
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
4
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa      ;;
4
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa      ;;
5
;; Distributed under terms of the GNU General Public License    ;;
5
;; Distributed under terms of the GNU General Public License    ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
7
 
8
$Revision: 2381 $
8
$Revision: 2455 $
9
 
9
 
10
 
10
 
11
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12
;; IRQ0 HANDLER (TIMER INTERRUPT) ;;
12
;; IRQ0 HANDLER (TIMER INTERRUPT) ;;
13
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
13
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
14
 
14
 
15
 
15
 
16
align 32
16
align 32
17
irq0:
17
irq0:
18
        pushad
18
        pushad
19
        Mov     ds, ax, app_data
19
        Mov     ds, ax, app_data
20
        mov     es, ax
20
        mov     es, ax
21
        inc     [timer_ticks]
21
        inc     [timer_ticks]
22
        mov     eax, [timer_ticks]
22
        mov     eax, [timer_ticks]
23
        call    playNote       ; <<<--- Speaker driver
23
        call    playNote       ; <<<--- Speaker driver
24
        sub     eax, [next_usage_update]
24
        sub     eax, [next_usage_update]
25
        cmp     eax, 100
25
        cmp     eax, 100
26
        jb      .nocounter
26
        jb      .nocounter
27
        add     [next_usage_update], 100
27
        add     [next_usage_update], 100
28
        call    updatecputimes
28
        call    updatecputimes
29
  .nocounter:
29
  .nocounter:
30
        xor     ecx, ecx        ; send End Of Interrupt signal
30
        xor     ecx, ecx        ; send End Of Interrupt signal
31
        call    irq_eoi
31
        call    irq_eoi
32
        btr     dword[DONT_SWITCH], 0
32
        btr     dword[DONT_SWITCH], 0
33
        jc      .return
33
        jc      .return
34
        call    find_next_task
34
        call    find_next_task
35
        jz      .return  ; if there is only one running process
35
        jz      .return  ; if there is only one running process
36
        call    do_change_task
36
        call    do_change_task
37
  .return:
37
  .return:
38
        popad
38
        popad
39
        iretd
39
        iretd
40
 
40
 
41
align 4
41
align 4
42
change_task:
42
change_task:
43
        pushfd
43
        pushfd
44
        cli
44
        cli
45
        pushad
45
        pushad
46
if 0
46
if 0
47
; \begin{Mario79} ; <- must be refractoried, if used...
47
; \begin{Mario79} ; <- must be refractoried, if used...
48
        cmp     [dma_task_switched], 1
48
        cmp     [dma_task_switched], 1
49
        jne     .find_next_task
49
        jne     .find_next_task
50
        mov     [dma_task_switched], 0
50
        mov     [dma_task_switched], 0
51
        mov     ebx, [dma_process]
51
        mov     ebx, [dma_process]
52
        cmp     [CURRENT_TASK], ebx
52
        cmp     [CURRENT_TASK], ebx
53
        je      .return
53
        je      .return
54
        mov     edi, [dma_slot_ptr]
54
        mov     edi, [dma_slot_ptr]
55
        mov     [CURRENT_TASK], ebx
55
        mov     [CURRENT_TASK], ebx
56
        mov     [TASK_BASE], edi
56
        mov     [TASK_BASE], edi
57
        jmp     @f
57
        jmp     @f
58
.find_next_task:
58
.find_next_task:
59
; \end{Mario79}
59
; \end{Mario79}
60
end if
60
end if
61
        call    find_next_task
61
        call    find_next_task
62
        jz      .return  ; the same task -> skip switch
62
        jz      .return  ; the same task -> skip switch
63
  @@:
63
  @@:
64
        mov     byte[DONT_SWITCH], 1
64
        mov     byte[DONT_SWITCH], 1
65
        call    do_change_task
65
        call    do_change_task
66
  .return:
66
  .return:
67
        popad
67
        popad
68
        popfd
68
        popfd
69
        ret
69
        ret
70
 
70
 
71
uglobal
71
uglobal
72
align 4
72
align 4
73
;  far_jump:
73
;  far_jump:
74
;   .offs dd ?
74
;   .offs dd ?
75
;   .sel  dw ?
75
;   .sel  dw ?
76
   context_counter     dd 0 ;noname & halyavin
76
   context_counter     dd 0 ;noname & halyavin
77
   next_usage_update   dd 0
77
   next_usage_update   dd 0
78
   timer_ticks         dd 0
78
   timer_ticks         dd 0
79
;  prev_slot           dd ?
79
;  prev_slot           dd ?
80
;  event_sched         dd ?
80
;  event_sched         dd ?
81
endg
81
endg
82
 
82
 
83
align 4
83
align 4
84
update_counters:
84
update_counters:
85
        mov     edi, [TASK_BASE]
85
        mov     edi, [TASK_BASE]
86
        rdtsc
86
        rdtsc
87
        sub     eax, [edi+TASKDATA.counter_add] ; time stamp counter add
87
        sub     eax, [edi+TASKDATA.counter_add] ; time stamp counter add
88
        add     [edi+TASKDATA.counter_sum], eax ; counter sum
88
        add     [edi+TASKDATA.counter_sum], eax ; counter sum
89
        ret
89
        ret
90
align 4
90
align 4
91
updatecputimes:
91
updatecputimes:
92
        xor     eax, eax
92
        xor     eax, eax
93
        xchg    eax, [idleuse]
93
        xchg    eax, [idleuse]
94
        mov     [idleusesec], eax
94
        mov     [idleusesec], eax
95
        mov     ecx, [TASK_COUNT]
95
        mov     ecx, [TASK_COUNT]
96
        mov     edi, TASK_DATA
96
        mov     edi, TASK_DATA
97
  .newupdate:
97
  .newupdate:
98
        xor     eax, eax
98
        xor     eax, eax
99
        xchg    eax, [edi+TASKDATA.counter_sum]
99
        xchg    eax, [edi+TASKDATA.counter_sum]
100
        mov     [edi+TASKDATA.cpu_usage], eax
100
        mov     [edi+TASKDATA.cpu_usage], eax
101
        add     edi, 0x20
101
        add     edi, 0x20
102
        loop    .newupdate
102
        loop    .newupdate
103
        ret
103
        ret
104
 
104
 
105
align 4
105
align 4
106
find_next_task:
106
find_next_task:
107
;info:
107
;info:
108
;   Find next task to execute
108
;   Find next task to execute
109
;retval:
109
;retval:
110
;   ebx = address of the APPDATA for the selected task (slot-base)
110
;   ebx = address of the APPDATA for the selected task (slot-base)
111
;   esi = previous slot-base ([current_slot] at the begin)
111
;   esi = previous slot-base ([current_slot] at the begin)
112
;   edi = address of the TASKDATA for the selected task
112
;   edi = address of the TASKDATA for the selected task
113
;   ZF  = 1  if the task is the same
113
;   ZF  = 1  if the task is the same
114
;warning:
114
;warning:
115
;   [CURRENT_TASK] = bh , [TASK_BASE] = edi -- as result
115
;   [CURRENT_TASK] = bh , [TASK_BASE] = edi -- as result
116
;   [current_slot] is not set to new value (ebx)!!!
116
;   [current_slot] is not set to new value (ebx)!!!
117
;scratched: eax,ecx
117
;scratched: eax,ecx
118
        call    update_counters ; edi := [TASK_BASE]
118
        call    update_counters ; edi := [TASK_BASE]
119
        Mov     esi, ebx, [current_slot]
119
        Mov     esi, ebx, [current_slot]
120
  .loop:
120
  .loop:
121
        cmp     bh, [TASK_COUNT]
121
        cmp     bh, [TASK_COUNT]
122
        jb      @f
122
        jb      @f
123
        xor     bh, bh
123
        xor     bh, bh
124
        mov     edi, CURRENT_TASK
124
        mov     edi, CURRENT_TASK
125
  @@:
125
  @@:
126
        inc     bh       ; ebx += APPDATA.size
126
        inc     bh       ; ebx += APPDATA.size
127
        add     edi, 0x20; edi += TASKDATA.size
127
        add     edi, 0x20; edi += TASKDATA.size
128
        mov     al, [edi+TASKDATA.state]
128
        mov     al, [edi+TASKDATA.state]
129
        test    al, al
129
        test    al, al
130
        jz      .found   ; state == 0
130
        jz      .found   ; state == 0
131
        cmp     al, 5
131
        cmp     al, 5
132
        jne     .loop    ; state == 1,2,3,4,9
132
        jne     .loop    ; state == 1,2,3,4,9
133
      ; state == 5
133
      ; state == 5
134
        pushad  ; more freedom for [APPDATA.wait_test]
134
        pushad  ; more freedom for [APPDATA.wait_test]
135
        call    [ebx+APPDATA.wait_test]
135
        call    [ebx+APPDATA.wait_test]
136
        mov     [esp+28], eax
136
        mov     [esp+28], eax
137
        popad
137
        popad
138
        or      eax, eax
138
        or      eax, eax
139
        jnz     @f
139
        jnz     @f
140
      ; testing for timeout
140
      ; testing for timeout
141
        mov     ecx, [timer_ticks]
141
        mov     ecx, [timer_ticks]
142
        sub     ecx, [ebx+APPDATA.wait_begin]
142
        sub     ecx, [ebx+APPDATA.wait_begin]
143
        cmp     ecx, [ebx+APPDATA.wait_timeout]
143
        cmp     ecx, [ebx+APPDATA.wait_timeout]
144
        jb      .loop
144
        jb      .loop
145
  @@:
145
  @@:
146
        mov     [ebx+APPDATA.wait_param], eax  ; retval for wait
146
        mov     [ebx+APPDATA.wait_param], eax  ; retval for wait
147
        mov     [edi+TASKDATA.state], 0
147
        mov     [edi+TASKDATA.state], 0
148
  .found:
148
  .found:
149
        mov     [CURRENT_TASK], bh
149
        mov     [CURRENT_TASK], bh
150
        mov     [TASK_BASE], edi
150
        mov     [TASK_BASE], edi
151
        rdtsc   ;call  _rdtsc
151
        rdtsc   ;call  _rdtsc
152
        mov     [edi+TASKDATA.counter_add], eax; for next using update_counters
152
        mov     [edi+TASKDATA.counter_add], eax; for next using update_counters
153
        cmp     ebx, esi ;esi - previous slot-base
153
        cmp     ebx, esi ;esi - previous slot-base
154
        ret
154
        ret
155
;TODO: Íàäî áû óáðàòü èñïîëüçîâàíèå do_change_task èç V86...
155
;TODO: Íàäî áû óáðàòü èñïîëüçîâàíèå do_change_task èç V86...
156
; è ïîñëå ýòîãî ïåðåíåñòè îáðàáîòêó TASKDATA.counter_add/sum â do_change_task
156
; è ïîñëå ýòîãî ïåðåíåñòè îáðàáîòêó TASKDATA.counter_add/sum â do_change_task
157
 
157
 
158
align 4
158
align 4
159
do_change_task:
159
do_change_task:
160
;param:
160
;param:
161
;   ebx = address of the APPDATA for incoming task (new)
161
;   ebx = address of the APPDATA for incoming task (new)
162
;warning:
162
;warning:
163
;   [CURRENT_TASK] and [TASK_BASE] must be changed before (e.g. in find_next_task)
163
;   [CURRENT_TASK] and [TASK_BASE] must be changed before (e.g. in find_next_task)
164
;   [current_slot] is the outcoming (old), and set here to a new value (ebx)
164
;   [current_slot] is the outcoming (old), and set here to a new value (ebx)
165
;scratched: eax,ecx,esi
165
;scratched: eax,ecx,esi
166
        mov     esi, ebx
166
        mov     esi, ebx
167
        xchg    esi, [current_slot]
167
        xchg    esi, [current_slot]
168
; set new stack after saving old
168
; set new stack after saving old
169
        mov     [esi+APPDATA.saved_esp], esp
169
        mov     [esi+APPDATA.saved_esp], esp
170
        mov     esp, [ebx+APPDATA.saved_esp]
170
        mov     esp, [ebx+APPDATA.saved_esp]
171
; set new thread io-map
171
; set new thread io-map
172
        Mov     dword [page_tabs+((tss._io_map_0 and -4096) shr 10)],eax,[ebx+APPDATA.io_map]
172
        Mov     dword [page_tabs+((tss._io_map_0 and -4096) shr 10)],eax,[ebx+APPDATA.io_map]
173
        Mov     dword [page_tabs+((tss._io_map_1 and -4096) shr 10)],eax,[ebx+APPDATA.io_map+4]
173
        Mov     dword [page_tabs+((tss._io_map_1 and -4096) shr 10)],eax,[ebx+APPDATA.io_map+4]
174
; set new thread memory-map
174
; set new thread memory-map
175
        mov     ecx, APPDATA.dir_table
175
        mov     ecx, APPDATA.dir_table
176
        mov     eax, [ebx+ecx]      ;offset>0x7F
176
        mov     eax, [ebx+ecx]      ;offset>0x7F
177
        cmp     eax, [esi+ecx]      ;offset>0x7F
177
        cmp     eax, [esi+ecx]      ;offset>0x7F
178
        je      @f
178
        je      @f
179
        mov     cr3, eax
179
        mov     cr3, eax
180
@@:
180
@@:
181
; set tss.esp0
181
; set tss.esp0
182
 
182
 
183
        Mov     [tss._esp0],eax,[ebx+APPDATA.saved_esp0]
183
        Mov     [tss._esp0],eax,[ebx+APPDATA.saved_esp0]
184
 
184
 
185
        mov     edx, [ebx+APPDATA.tls_base]
185
        mov     edx, [ebx+APPDATA.tls_base]
186
        cmp     edx, [esi+APPDATA.tls_base]
186
        cmp     edx, [esi+APPDATA.tls_base]
187
        je      @f
187
        je      @f
188
 
188
 
189
        mov     [tls_data_l+2], dx
189
        mov     [tls_data_l+2], dx
190
        shr     edx, 16
190
        shr     edx, 16
191
        mov     [tls_data_l+4], dl
191
        mov     [tls_data_l+4], dl
192
        mov     [tls_data_l+7], dh
192
        mov     [tls_data_l+7], dh
193
 
193
 
194
        mov     dx, app_tls
194
        mov     dx, app_tls
195
        mov     fs, dx
195
        mov     fs, dx
196
@@:
196
@@:
197
; set gs selector unconditionally
197
; set gs selector unconditionally
198
        Mov     gs,ax,graph_data
198
        Mov     gs,ax,graph_data
199
      ; set CR0.TS
199
      ; set CR0.TS
200
        cmp     bh, byte[fpu_owner] ;bh == incoming task (new)
200
        cmp     bh, byte[fpu_owner] ;bh == incoming task (new)
201
        clts                        ;clear a task switch flag
201
        clts                        ;clear a task switch flag
202
        je      @f
202
        je      @f
203
        mov     eax, cr0            ;and set it again if the owner
203
        mov     eax, cr0            ;and set it again if the owner
204
        or      eax, CR0_TS         ;of a fpu has changed
204
        or      eax, CR0_TS         ;of a fpu has changed
205
        mov     cr0, eax
205
        mov     cr0, eax
206
  @@: ; set context_counter (only for user pleasure ???)
206
  @@: ; set context_counter (only for user pleasure ???)
207
        inc     [context_counter]   ;noname & halyavin
207
        inc     [context_counter]   ;noname & halyavin
208
      ; set debug-registers, if it's necessary
208
      ; set debug-registers, if it's necessary
209
        test    byte[ebx+APPDATA.dbg_state], 1
209
        test    byte[ebx+APPDATA.dbg_state], 1
210
        jz      @f
210
        jz      @f
211
        xor     eax, eax
211
        xor     eax, eax
212
        mov     dr6, eax
212
        mov     dr6, eax
213
        lea     esi, [ebx+ecx+APPDATA.dbg_regs-APPDATA.dir_table];offset>0x7F
213
        lea     esi, [ebx+ecx+APPDATA.dbg_regs-APPDATA.dir_table];offset>0x7F
214
        cld
214
        cld
215
  macro lodsReg [reg] {
215
  macro lodsReg [reg] {
216
        lodsd
216
        lodsd
217
        mov     reg, eax
217
        mov     reg, eax
218
  }     lodsReg dr0, dr1, dr2, dr3, dr7
218
  }     lodsReg dr0, dr1, dr2, dr3, dr7
219
  purge lodsReg
219
  purge lodsReg
220
  @@:
220
  @@:
221
        ret
221
        ret
222
;end.
222
;end.
223
 
223
 
224
 
224
 
225
 
225
 
226
struct  MUTEX_WAITER
226
struct  MUTEX_WAITER
227
        list    LHEAD
227
        list    LHEAD
228
        task    dd ?
228
        task    dd ?
229
ends
229
ends
230
 
230
 
231
;void  __fastcall mutex_init(struct mutex *lock)
231
;void  __fastcall mutex_init(struct mutex *lock)
232
 
232
 
233
align 4
233
align 4
234
mutex_init:
234
mutex_init:
235
        mov     [ecx+MUTEX.lhead.next], ecx
235
        mov     [ecx+MUTEX.lhead.next], ecx
236
        mov     [ecx+MUTEX.lhead.prev], ecx
236
        mov     [ecx+MUTEX.lhead.prev], ecx
237
        mov     [ecx+MUTEX.count], 1
237
        mov     [ecx+MUTEX.count], 1
238
        ret
238
        ret
239
 
239
 
240
 
240
 
241
;void  __fastcall mutex_lock(struct mutex *lock)
241
;void  __fastcall mutex_lock(struct mutex *lock)
242
 
242
 
243
align 4
243
align 4
244
mutex_lock:
244
mutex_lock:
245
 
245
 
246
        dec     [ecx+MUTEX.count]
246
        dec     [ecx+MUTEX.count]
247
        jns     .done
247
        jns     .done
248
 
248
 
249
        pushfd
249
        pushfd
250
        cli
250
        cli
251
 
251
 
252
        sub     esp, sizeof.MUTEX_WAITER
252
        sub     esp, sizeof.MUTEX_WAITER
253
 
253
 
254
        list_add_tail esp, ecx      ;esp= new waiter, ecx= list head
254
        list_add_tail esp, ecx      ;esp= new waiter, ecx= list head
255
 
255
 
256
        mov     edx, [TASK_BASE]
256
        mov     edx, [TASK_BASE]
257
        mov     [esp+MUTEX_WAITER.task], edx
257
        mov     [esp+MUTEX_WAITER.task], edx
258
 
258
 
259
.forever:
259
.forever:
260
 
260
 
261
        mov     eax, -1
261
        mov     eax, -1
262
        xchg    eax, [ecx+MUTEX.count]
262
        xchg    eax, [ecx+MUTEX.count]
263
        dec     eax
263
        dec     eax
264
        jz      @F
264
        jz      @F
265
 
265
 
266
        mov     [edx+TASKDATA.state], 1
266
        mov     [edx+TASKDATA.state], 1
267
        call    change_task
267
        call    change_task
268
        jmp     .forever
268
        jmp     .forever
269
@@:
269
@@:
270
        mov     edx, [esp+MUTEX_WAITER.list.next]
270
        mov     edx, [esp+MUTEX_WAITER.list.next]
271
        mov     eax, [esp+MUTEX_WAITER.list.prev]
271
        mov     eax, [esp+MUTEX_WAITER.list.prev]
272
 
272
 
273
        mov     [eax+MUTEX_WAITER.list.next], edx
273
        mov     [eax+MUTEX_WAITER.list.next], edx
274
        mov     [edx+MUTEX_WAITER.list.prev], eax
274
        mov     [edx+MUTEX_WAITER.list.prev], eax
275
        cmp     [ecx+MUTEX.lhead.next], ecx
275
        cmp     [ecx+MUTEX.lhead.next], ecx
276
        jne     @F
276
        jne     @F
277
 
277
 
278
        mov     [ecx+MUTEX.count], 0
278
        mov     [ecx+MUTEX.count], 0
279
@@:
279
@@:
280
        add     esp, sizeof.MUTEX_WAITER
280
        add     esp, sizeof.MUTEX_WAITER
281
 
281
 
282
        popfd
282
        popfd
283
.done:
283
.done:
284
        ret
284
        ret
285
 
285
 
286
;void  __fastcall mutex_unlock(struct mutex *lock)
286
;void  __fastcall mutex_unlock(struct mutex *lock)
287
 
287
 
288
align 4
288
align 4
289
mutex_unlock:
289
mutex_unlock:
290
 
290
 
291
        pushfd
291
        pushfd
292
        cli
292
        cli
293
 
293
 
294
        mov     eax, [ecx+MUTEX.lhead.next]
294
        mov     eax, [ecx+MUTEX.lhead.next]
295
        cmp     eax, ecx
295
        cmp     eax, ecx
296
        mov     [ecx+MUTEX.count], 1
296
        mov     [ecx+MUTEX.count], 1
297
        je      @F
297
        je      @F
298
 
298
 
299
        mov     eax, [eax+MUTEX_WAITER.task]
299
        mov     eax, [eax+MUTEX_WAITER.task]
300
        mov     [eax+TASKDATA.state], 0
300
        mov     [eax+TASKDATA.state], 0
301
@@:
301
@@:
302
        popfd
302
        popfd
303
        ret
303
        ret
304
 
304
 
305
 
305
 
306
purge MUTEX_WAITER
306
purge MUTEX_WAITER
307
 
307
 
308
if 0
308
if 0
309
 
309
 
310
struc TIMER
310
struc TIMER
311
{
311
{
312
  .next      dd ?
312
  .next      dd ?
313
  .exp_time  dd ?
313
  .exp_time  dd ?
314
  .func      dd ?
314
  .func      dd ?
315
  .arg       dd ?
315
  .arg       dd ?
316
}
316
}
317
 
317
 
318
 
318
 
319
MAX_PROIRITY         0   ; highest, used for kernel tasks
319
MAX_PROIRITY         0   ; highest, used for kernel tasks
320
MAX_USER_PRIORITY    0   ; highest priority for user processes
320
MAX_USER_PRIORITY    0   ; highest priority for user processes
321
USER_PRIORITY        7   ; default (should correspond to nice 0)
321
USER_PRIORITY        7   ; default (should correspond to nice 0)
322
MIN_USER_PRIORITY   14   ; minimum priority for user processes
322
MIN_USER_PRIORITY   14   ; minimum priority for user processes
323
IDLE_PRIORITY       15   ; lowest, only IDLE process goes here
323
IDLE_PRIORITY       15   ; lowest, only IDLE process goes here
324
NR_SCHED_QUEUES     16   ; MUST equal IDLE_PRIORYTY + 1
324
NR_SCHED_QUEUES     16   ; MUST equal IDLE_PRIORYTY + 1
325
 
325
 
326
uglobal
326
uglobal
327
rdy_head   rd 16
327
rdy_head   rd 16
328
endg
328
endg
329
 
329
 
330
align 4
330
align 4
331
pick_task:
331
pick_task:
332
 
332
 
333
        xor     eax, eax
333
        xor     eax, eax
334
  .pick:
334
  .pick:
335
        mov     ebx, [rdy_head+eax*4]
335
        mov     ebx, [rdy_head+eax*4]
336
        test    ebx, ebx
336
        test    ebx, ebx
337
        jz      .next
337
        jz      .next
338
 
338
 
339
        mov     [next_task], ebx
339
        mov     [next_task], ebx
340
        test    [ebx+flags.billable]
340
        test    [ebx+flags.billable]
341
        jz      @F
341
        jz      @F
342
        mov     [bill_task], ebx
342
        mov     [bill_task], ebx
343
  @@:
343
  @@:
344
        ret
344
        ret
345
  .next:
345
  .next:
346
        inc     eax
346
        inc     eax
347
        jmp     .pick
347
        jmp     .pick
348
 
348
 
349
; param
349
; param
350
;  eax= task
350
;  eax= task
351
;
351
;
352
; retval
352
; retval
353
;  eax= task
353
;  eax= task
354
;  ebx= queue
354
;  ebx= queue
355
;  ecx= front if 1 or back if 0
355
;  ecx= front if 1 or back if 0
356
align 4
356
align 4
357
shed:
357
shed:
358
        cmp     [eax+.tics_left], 0;signed compare
358
        cmp     [eax+.tics_left], 0;signed compare
359
        mov     ebx, [eax+.priority]
359
        mov     ebx, [eax+.priority]
360
        setg    ecx
360
        setg    ecx
361
        jg      @F
361
        jg      @F
362
 
362
 
363
        mov     edx, [eax+.tics_quantum]
363
        mov     edx, [eax+.tics_quantum]
364
        mov     [eax+.ticks_left], edx
364
        mov     [eax+.ticks_left], edx
365
        cmp     ebx, (IDLE_PRIORITY-1)
365
        cmp     ebx, (IDLE_PRIORITY-1)
366
        je      @F
366
        je      @F
367
        inc     ebx
367
        inc     ebx
368
  @@:
368
  @@:
369
        ret
369
        ret
370
 
370
 
371
; param
371
; param
372
;  eax= task
372
;  eax= task
373
align 4
373
align 4
374
enqueue:
374
enqueue:
375
        call    shed;eax
375
        call    shed;eax
376
        cmp     [rdy_head+ebx*4], 0
376
        cmp     [rdy_head+ebx*4], 0
377
        jnz     @F
377
        jnz     @F
378
 
378
 
379
        mov     [rdy_head+ebx*4], eax
379
        mov     [rdy_head+ebx*4], eax
380
        mov     [rdy_tail+ebx*4], eax
380
        mov     [rdy_tail+ebx*4], eax
381
        mov     [eax+.next_ready], 0
381
        mov     [eax+.next_ready], 0
382
        jmp     .pick
382
        jmp     .pick
383
  @@:
383
  @@:
384
        test    ecx, ecx
384
        test    ecx, ecx
385
        jz      .back
385
        jz      .back
386
 
386
 
387
        mov     ecx, [rdy_head+ebx*4]
387
        mov     ecx, [rdy_head+ebx*4]
388
        mov     [eax+.next_ready], ecx
388
        mov     [eax+.next_ready], ecx
389
        mov     [rdy_head+ebx*4], eax
389
        mov     [rdy_head+ebx*4], eax
390
        jmp     .pick
390
        jmp     .pick
391
  .back:
391
  .back:
392
        mov     ecx, [rdy_tail+ebx*4]
392
        mov     ecx, [rdy_tail+ebx*4]
393
        mov     [ecx+.next_ready], eax
393
        mov     [ecx+.next_ready], eax
394
        mov     [rdy_tail+ebx*4], eax
394
        mov     [rdy_tail+ebx*4], eax
395
        mov     [eax+.next_ready], 0
395
        mov     [eax+.next_ready], 0
396
  .pick:
396
  .pick:
397
        call    pick_proc;select next task
397
        call    pick_proc;select next task
398
        ret
398
        ret
399
 
399
 
400
end if
400
end if