Subversion Repositories Kolibri OS

Rev

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

Rev 4459 Rev 4923
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;;                                                              ;;
6
;;                                                              ;;
7
;;  MenuetOS process management, protected ring3                ;;
7
;;  MenuetOS process management, protected ring3                ;;
8
;;                                                              ;;
8
;;                                                              ;;
9
;;  Distributed under GPL. See file COPYING for details.        ;;
9
;;  Distributed under GPL. See file COPYING for details.        ;;
10
;;  Copyright 2003 Ville Turjanmaa                              ;;
10
;;  Copyright 2003 Ville Turjanmaa                              ;;
11
;;                                                              ;;
11
;;                                                              ;;
12
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
13
 
13
 
14
$Revision: 4313 $
14
$Revision: 4313 $
15
 
15
 
16
align 4 ;3A08
16
align 4 ;3A08
17
build_interrupt_table:
17
build_interrupt_table:
18
        mov     edi, idts
18
        mov     edi, idts
19
        mov     esi, sys_int
19
        mov     esi, sys_int
20
        mov     ecx, 0x40
20
        mov     ecx, 0x40
21
        mov     eax, (10001110b shl 24) + os_code
21
        mov     eax, (10001110b shl 24) + os_code
22
  @@:
22
  @@:
23
        movsw   ;low word of code-entry
23
        movsw   ;low word of code-entry
24
        stosd   ;interrupt gate type : os_code selector
24
        stosd   ;interrupt gate type : os_code selector
25
        movsw   ;high word of code-entry
25
        movsw   ;high word of code-entry
26
        loop    @b
26
        loop    @b
27
        movsd   ;copy low  dword of trap gate for int 0x40
27
        movsd   ;copy low  dword of trap gate for int 0x40
28
        movsd   ;copy high dword of trap gate for int 0x40
28
        movsd   ;copy high dword of trap gate for int 0x40
29
        lidt    [esi]
29
        lidt    [esi]
30
        ret
30
        ret
31
 
31
 
32
iglobal
32
iglobal
33
  align 4
33
  align 4
34
  sys_int:
34
  sys_int:
35
    ;exception handlers addresses (for interrupt gate construction)
35
    ;exception handlers addresses (for interrupt gate construction)
36
        dd      e0,e1,e2,e3,e4,e5,e6,except_7 ; SEE: core/fpu.inc
36
        dd      e0,e1,e2,e3,e4,e5,e6,except_7 ; SEE: core/fpu.inc
37
        dd      e8,e9,e10,e11,e12,e13,page_fault_exc,e15
37
        dd      e8,e9,e10,e11,e12,e13,page_fault_exc,e15
38
        dd      e16, e17,e18, e19
38
        dd      e16, e17,e18, e19
39
        times   12 dd unknown_interrupt ;int_20..int_31
39
        times   12 dd unknown_interrupt ;int_20..int_31
40
 
40
 
41
    ;interrupt handlers addresses (for interrupt gate construction)
41
    ;interrupt handlers addresses (for interrupt gate construction)
42
        ; 0x20 .. 0x2F - IRQ handlers
42
        ; 0x20 .. 0x2F - IRQ handlers
43
        dd      irq0, irq_serv.irq_1, irq_serv.irq_2
43
        dd      irq0, irq_serv.irq_1, irq_serv.irq_2
44
        dd      irq_serv.irq_3, irq_serv.irq_4
44
        dd      irq_serv.irq_3, irq_serv.irq_4
45
        dd      irq_serv.irq_5,  irq_serv.irq_6,  irq_serv.irq_7
45
        dd      irq_serv.irq_5,  irq_serv.irq_6,  irq_serv.irq_7
46
        dd      irq_serv.irq_8,  irq_serv.irq_9,  irq_serv.irq_10
46
        dd      irq_serv.irq_8,  irq_serv.irq_9,  irq_serv.irq_10
47
        dd      irq_serv.irq_11, irq_serv.irq_12, irqD, irq_serv.irq_14, irq_serv.irq_15
47
        dd      irq_serv.irq_11, irq_serv.irq_12, irqD, irq_serv.irq_14, irq_serv.irq_15
48
        dd irq_serv.irq_16
48
        dd irq_serv.irq_16
49
        dd irq_serv.irq_17
49
        dd irq_serv.irq_17
50
        dd irq_serv.irq_18
50
        dd irq_serv.irq_18
51
        dd irq_serv.irq_19
51
        dd irq_serv.irq_19
52
        dd irq_serv.irq_20
52
        dd irq_serv.irq_20
53
        dd irq_serv.irq_21
53
        dd irq_serv.irq_21
54
        dd irq_serv.irq_22
54
        dd irq_serv.irq_22
55
        dd irq_serv.irq_23
55
        dd irq_serv.irq_23
56
 
56
 
57
    times 32 - IRQ_RESERVED dd unknown_interrupt
57
    times 32 - IRQ_RESERVED dd unknown_interrupt
58
    ;int_0x40 gate trap (for directly copied)
58
    ;int_0x40 gate trap (for directly copied)
59
        dw      i40 and 0xFFFF, os_code, 11101111b shl 8, i40 shr 16
59
        dw      i40 and 0xFFFF, os_code, 11101111b shl 8, i40 shr 16
60
 
60
 
61
  idtreg: ; data for LIDT instruction (!!! must be immediately below sys_int data)
61
  idtreg: ; data for LIDT instruction (!!! must be immediately below sys_int data)
62
        dw      2*($-sys_int-4)-1
62
        dw      2*($-sys_int-4)-1
63
        dd      idts ;0x8000B100
63
        dd      idts ;0x8000B100
64
        dw      0    ;просто выравнивание
64
        dw      0    ;просто выравнивание
65
 
65
 
66
  msg_fault_sel dd  msg_exc_8,msg_exc_u,msg_exc_a,msg_exc_b
66
  msg_fault_sel dd  msg_exc_8,msg_exc_u,msg_exc_a,msg_exc_b
67
                dd  msg_exc_c,msg_exc_d,msg_exc_e
67
                dd  msg_exc_c,msg_exc_d,msg_exc_e
68
 
68
 
69
  msg_exc_8     db "Double fault", 0
69
  msg_exc_8     db "Double fault", 0
70
  msg_exc_u     db "Undefined Exception", 0
70
  msg_exc_u     db "Undefined Exception", 0
71
  msg_exc_a     db "Invalid TSS", 0
71
  msg_exc_a     db "Invalid TSS", 0
72
  msg_exc_b     db "Segment not present", 0
72
  msg_exc_b     db "Segment not present", 0
73
  msg_exc_c     db "Stack fault", 0
73
  msg_exc_c     db "Stack fault", 0
74
  msg_exc_d     db "General protection fault", 0
74
  msg_exc_d     db "General protection fault", 0
75
  msg_exc_e     db "Page fault", 0
75
  msg_exc_e     db "Page fault", 0
76
 
76
 
77
  if lang eq sp
77
  if lang eq sp
78
    include 'core/sys32-sp.inc'
78
    include 'core/sys32-sp.inc'
79
  else
79
  else
80
    msg_sel_ker   db "kernel", 0
80
    msg_sel_ker   db "kernel", 0
81
    msg_sel_app   db "application", 0
81
    msg_sel_app   db "application", 0
82
  end if
82
  end if
83
 
83
 
84
endg
84
endg
85
 
85
 
86
macro save_ring3_context {
86
macro save_ring3_context {
87
        pushad
87
        pushad
88
}
88
}
89
macro restore_ring3_context {
89
macro restore_ring3_context {
90
        popad
90
        popad
91
}
91
}
92
macro exc_wo_code [num] {
92
macro exc_wo_code [num] {
93
  e#num :
93
  e#num :
94
        save_ring3_context
94
        save_ring3_context
95
        mov     bl, num
95
        mov     bl, num
96
        jmp     exc_c
96
        jmp     exc_c
97
} exc_wo_code   0,1,2,3,4,5,6,15,16,19
97
} exc_wo_code   0,1,2,3,4,5,6,15,16,19
98
 
98
 
99
macro exc_w_code [num] {
99
macro exc_w_code [num] {
100
  e#num :
100
  e#num :
101
        add     esp, 4
101
        add     esp, 4
102
        save_ring3_context
102
        save_ring3_context
103
        mov     bl, num
103
        mov     bl, num
104
        jmp     exc_c
104
        jmp     exc_c
105
} exc_w_code    8,9,10,11,12,13,17,18
105
} exc_w_code    8,9,10,11,12,13,17,18
106
 
106
 
107
 
107
 
108
uglobal
108
uglobal
109
  pf_err_code   dd ?
109
  pf_err_code   dd ?
110
endg
110
endg
111
 
111
 
112
page_fault_exc:                 ; дуракоусточивость: селекторы испорчены...
112
page_fault_exc:                 ; дуракоусточивость: селекторы испорчены...
113
        pop     [ss:pf_err_code]; действительно до следующего #PF
113
        pop     [ss:pf_err_code]; действительно до следующего #PF
114
        save_ring3_context
114
        save_ring3_context
115
        mov     bl, 14
115
        mov     bl, 14
116
 
116
 
117
exc_c:                          ; исключения (все, кроме 7-го - #NM)
117
exc_c:                          ; исключения (все, кроме 7-го - #NM)
118
; Фрэйм стека при исключении/прерывании из 3-го кольца + pushad (т.е., именно здесь)
118
; Фрэйм стека при исключении/прерывании из 3-го кольца + pushad (т.е., именно здесь)
119
  reg_ss        equ esp+0x30
119
  reg_ss        equ esp+0x30
120
  reg_esp3      equ esp+0x2C
120
  reg_esp3      equ esp+0x2C
121
  reg_eflags    equ esp+0x28
121
  reg_eflags    equ esp+0x28
122
  reg_cs3       equ esp+0x24
122
  reg_cs3       equ esp+0x24
123
  reg_eip       equ esp+0x20
123
  reg_eip       equ esp+0x20
124
 ; это фрэйм от pushad
124
 ; это фрэйм от pushad
125
  reg_eax       equ esp+0x1C
125
  reg_eax       equ esp+0x1C
126
  reg_ecx       equ esp+0x18
126
  reg_ecx       equ esp+0x18
127
  reg_edx       equ esp+0x14
127
  reg_edx       equ esp+0x14
128
  reg_ebx       equ esp+0x10
128
  reg_ebx       equ esp+0x10
129
  reg_esp0      equ esp+0x0C
129
  reg_esp0      equ esp+0x0C
130
  reg_ebp       equ esp+0x08
130
  reg_ebp       equ esp+0x08
131
  reg_esi       equ esp+0x04
131
  reg_esi       equ esp+0x04
132
  reg_edi       equ esp+0x00
132
  reg_edi       equ esp+0x00
133
 
133
 
134
        mov     ax, app_data        ;исключение
134
        mov     ax, app_data        ;исключение
135
        mov     ds, ax                  ;загрузим правильные значения
135
        mov     ds, ax                  ;загрузим правильные значения
136
        mov     es, ax                  ;в регистры
136
        mov     es, ax                  ;в регистры
137
        cld                     ; и приводим DF к стандарту
137
        cld                     ; и приводим DF к стандарту
138
        movzx   ebx, bl
138
        movzx   ebx, bl
139
; redirect to V86 manager? (EFLAGS & 0x20000) != 0?
139
; redirect to V86 manager? (EFLAGS & 0x20000) != 0?
140
        test    byte[reg_eflags+2], 2
140
        test    byte[reg_eflags+2], 2
141
        jnz     v86_exc_c
141
        jnz     v86_exc_c
142
        cmp     bl, 14          ; #PF
142
        cmp     bl, 14          ; #PF
143
        jne     @f
143
        jne     @f
144
        call    page_fault_handler ; SEE: core/memory.inc
144
        call    page_fault_handler ; SEE: core/memory.inc
145
  @@:
145
  @@:
146
        mov     esi, [current_slot]
146
        mov     esi, [current_slot]
147
        btr     [esi+APPDATA.except_mask], ebx
147
        btr     [esi+APPDATA.except_mask], ebx
148
        jnc     @f
148
        jnc     @f
149
        mov     eax, [esi+APPDATA.exc_handler]
149
        mov     eax, [esi+APPDATA.exc_handler]
150
        test    eax, eax
150
        test    eax, eax
151
        jnz     IRetToUserHook
151
        jnz     IRetToUserHook
152
  @@:
152
  @@:
153
        cli
153
        cli
154
        mov     eax, [esi+APPDATA.debugger_slot]
154
        mov     eax, [esi+APPDATA.debugger_slot]
155
        test    eax, eax
155
        test    eax, eax
156
        jnz     .debug
156
        jnz     .debug
157
        sti
157
        sti
158
; not debuggee => say error and terminate
158
; not debuggee => say error and terminate
159
        call    show_error_parameters ;; only ONE using, inline ???
159
        call    show_error_parameters ;; only ONE using, inline ???
160
       ;mov     edx, [TASK_BASE]
160
       ;mov     edx, [TASK_BASE]
161
        mov     [edx + TASKDATA.state], byte 4 ; terminate
161
        mov     [edx + TASKDATA.state], byte 4 ; terminate
162
        call    wakeup_osloop
162
        call    wakeup_osloop
163
        call    change_task
163
        call    change_task
164
; If we're here, then the main OS thread has crashed before initializing IDLE thread.
164
; If we're here, then the main OS thread has crashed before initializing IDLE thread.
165
; Or they both have crashed. Anyway, things are hopelessly broken.
165
; Or they both have crashed. Anyway, things are hopelessly broken.
166
        hlt
166
        hlt
167
        jmp     $-1
167
        jmp     $-1
168
.debug:
168
.debug:
169
; we are debugged process, notify debugger and suspend ourself
169
; we are debugged process, notify debugger and suspend ourself
170
; eax=debugger PID
170
; eax=debugger PID
171
        mov     ecx, 1          ; debug_message code=other_exception
171
        mov     ecx, 1          ; debug_message code=other_exception
172
        cmp     bl, 1           ; #DB
172
        cmp     bl, 1           ; #DB
173
        jne     .notify         ; notify debugger and suspend ourself
173
        jne     .notify         ; notify debugger and suspend ourself
174
        mov     ebx, dr6        ; debug_message data=DR6_image
174
        mov     ebx, dr6        ; debug_message data=DR6_image
175
        xor     edx, edx
175
        xor     edx, edx
176
        mov     dr6, edx
176
        mov     dr6, edx
177
        mov     edx, dr7
177
        mov     edx, dr7
178
        mov     cl, not 8
178
        mov     cl, not 8
179
  .l1:
179
  .l1:
180
        shl     dl, 2
180
        shl     dl, 2
181
        jc      @f
181
        jc      @f
182
        and     bl, cl
182
        and     bl, cl
183
  @@:
183
  @@:
184
        sar     cl, 1
184
        sar     cl, 1
185
        jc      .l1
185
        jc      .l1
186
        mov     cl, 3           ; debug_message code=debug_exception
186
        mov     cl, 3           ; debug_message code=debug_exception
187
.notify:
187
.notify:
188
        push    ebx             ; debug_message data
188
        push    ebx             ; debug_message data
189
        mov     ebx, [TASK_BASE]
189
        mov     ebx, [TASK_BASE]
190
        push    [ebx+TASKDATA.pid] ; PID
190
        push    [ebx+TASKDATA.pid] ; PID
191
        push    ecx             ; debug_message code ((here: ecx==1/3))
191
        push    ecx             ; debug_message code ((here: ecx==1/3))
192
        mov     cl, 12          ; debug_message size
192
        mov     cl, 12          ; debug_message size
193
        call    debugger_notify ;; only ONE using, inline ??? SEE: core/debug.inc
193
        call    debugger_notify ;; only ONE using, inline ??? SEE: core/debug.inc
194
        add     esp, 12
194
        add     esp, 12
195
        mov     edx, [TASK_BASE]
195
        mov     edx, [TASK_BASE]
196
        mov     byte [edx+TASKDATA.state], 1 ; suspended
196
        mov     byte [edx+TASKDATA.state], 1 ; suspended
197
        call    change_task     ; SEE: core/shed.inc
197
        call    change_task     ; SEE: core/shed.inc
198
        restore_ring3_context
198
        restore_ring3_context
199
        iretd
199
        iretd
200
 
200
 
201
IRetToUserHook:
201
IRetToUserHook:
202
        xchg    eax, [reg_eip]
202
        xchg    eax, [reg_eip]
203
        sub     dword[reg_esp3], 8
203
        sub     dword[reg_esp3], 8
204
        mov     edi, [reg_esp3]
204
        mov     edi, [reg_esp3]
205
        stosd
205
        stosd
206
        mov     [edi], ebx
206
        mov     [edi], ebx
207
        restore_ring3_context
207
        restore_ring3_context
208
; simply return control to interrupted process
208
; simply return control to interrupted process
209
unknown_interrupt:
209
unknown_interrupt:
210
        iretd
210
        iretd
211
 
211
 
212
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
212
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
213
; bl - error vector
213
; bl - error vector
214
show_error_parameters:
214
show_error_parameters:
215
        cmp     bl, 0x06
215
        cmp     bl, 0x06
216
        jnz     .no_ud
216
        jnz     .no_ud
217
        push    ebx
217
        push    ebx
218
        mov     ebx, ud_user_message
218
        mov     ebx, ud_user_message
219
        mov     ebp, notifyapp
219
        mov     ebp, notifyapp
220
        call    fs_execute_from_sysdir_param
220
        call    fs_execute_from_sysdir_param
221
        pop     ebx
221
        pop     ebx
222
.no_ud:
222
.no_ud:
223
        mov     edx, [TASK_BASE];not scratched below
223
        mov     edx, [TASK_BASE];not scratched below
224
        if lang eq sp
224
        if lang eq sp
225
        DEBUGF  1, "K : Proceso - terminado forzado PID: %x [%s]\n", [edx+TASKDATA.pid], [current_slot]
225
        DEBUGF  1, "K : Proceso - terminado forzado PID: %x [%s]\n", [edx+TASKDATA.pid], [current_slot]
226
        else
226
        else
227
        DEBUGF  1, "K : Process - forced terminate PID: %x [%s]\n", [edx+TASKDATA.pid], [current_slot]
227
        DEBUGF  1, "K : Process - forced terminate PID: %x [%s]\n", [edx+TASKDATA.pid], [current_slot]
228
        end if
228
        end if
229
        cmp     bl, 0x08
229
        cmp     bl, 0x08
230
        jb      .l0
230
        jb      .l0
231
        cmp     bl, 0x0e
231
        cmp     bl, 0x0e
232
        jbe     .l1
232
        jbe     .l1
233
  .l0:
233
  .l0:
234
        mov     bl, 0x09
234
        mov     bl, 0x09
235
  .l1:
235
  .l1:
236
        mov     eax, [msg_fault_sel+ebx*4 - 0x08*4]
236
        mov     eax, [msg_fault_sel+ebx*4 - 0x08*4]
237
        DEBUGF  1, "K : %s\n", eax
237
        DEBUGF  1, "K : %s\n", eax
238
        mov     eax, [reg_cs3+4]
238
        mov     eax, [reg_cs3+4]
239
        mov     edi, msg_sel_app
239
        mov     edi, msg_sel_app
240
        mov     ebx, [reg_esp3+4]
240
        mov     ebx, [reg_esp3+4]
241
        cmp     eax, app_code
241
        cmp     eax, app_code
242
        je      @f
242
        je      @f
243
        mov     edi, msg_sel_ker
243
        mov     edi, msg_sel_ker
244
        mov     ebx, [reg_esp0+4]
244
        mov     ebx, [reg_esp0+4]
245
    @@:
245
    @@:
246
        DEBUGF  1, "K : EAX : %x EBX : %x ECX : %x\n", [reg_eax+4], [reg_ebx+4], [reg_ecx+4]
246
        DEBUGF  1, "K : EAX : %x EBX : %x ECX : %x\n", [reg_eax+4], [reg_ebx+4], [reg_ecx+4]
247
        DEBUGF  1, "K : EDX : %x ESI : %x EDI : %x\n", [reg_edx+4], [reg_esi+4], [reg_edi+4]
247
        DEBUGF  1, "K : EDX : %x ESI : %x EDI : %x\n", [reg_edx+4], [reg_esi+4], [reg_edi+4]
248
        DEBUGF  1, "K : EBP : %x EIP : %x ESP : %x\n", [reg_ebp+4], [reg_eip+4], ebx
248
        DEBUGF  1, "K : EBP : %x EIP : %x ESP : %x\n", [reg_ebp+4], [reg_eip+4], ebx
249
        DEBUGF  1, "K : Flags : %x CS : %x (%s)\n", [reg_eflags+4], eax, edi
249
        DEBUGF  1, "K : Flags : %x CS : %x (%s)\n", [reg_eflags+4], eax, edi
250
 
250
 
251
        DEBUGF  1, "K : Stack dump:\n"
251
        DEBUGF  1, "K : Stack dump:\n"
252
        push    eax ebx ecx edx
252
        push    eax ebx ecx edx
253
        call    .check_ESP
253
        call    .check_ESP
254
        test    eax, eax
254
        test    eax, eax
255
        jnz     .error_ESP
255
        jnz     .error_ESP
256
        DEBUGF  1, "K : [ESP+00]: %x",[ebx]
256
        DEBUGF  1, "K : [ESP+00]: %x",[ebx]
257
        add     ebx, 4
257
        add     ebx, 4
258
        call    .check_ESP
258
        call    .check_ESP
259
        test    eax, eax
259
        test    eax, eax
260
        jnz     .error_ESP
260
        jnz     .error_ESP
261
        DEBUGF  1, " [ESP+04]: %x",[ebx]
261
        DEBUGF  1, " [ESP+04]: %x",[ebx]
262
        add     ebx, 4
262
        add     ebx, 4
263
        call    .check_ESP
263
        call    .check_ESP
264
        test    eax, eax
264
        test    eax, eax
265
        jnz     .error_ESP
265
        jnz     .error_ESP
266
        DEBUGF  1, " [ESP+08]: %x\n",[ebx]
266
        DEBUGF  1, " [ESP+08]: %x\n",[ebx]
267
        add     ebx, 4
267
        add     ebx, 4
268
        call    .check_ESP
268
        call    .check_ESP
269
        test    eax, eax
269
        test    eax, eax
270
        jnz     .error_ESP
270
        jnz     .error_ESP
271
        DEBUGF  1, "K : [ESP+12]: %x",[ebx]
271
        DEBUGF  1, "K : [ESP+12]: %x",[ebx]
272
        add     ebx, 4
272
        add     ebx, 4
273
        call    .check_ESP
273
        call    .check_ESP
274
        test    eax, eax
274
        test    eax, eax
275
        jnz     .error_ESP
275
        jnz     .error_ESP
276
        DEBUGF  1, " [ESP+16]: %x",[ebx]
276
        DEBUGF  1, " [ESP+16]: %x",[ebx]
277
        add     ebx, 4
277
        add     ebx, 4
278
        call    .check_ESP
278
        call    .check_ESP
279
        test    eax, eax
279
        test    eax, eax
280
        jnz     .error_ESP
280
        jnz     .error_ESP
281
        DEBUGF  1, " [ESP+20]: %x\n",[ebx]
281
        DEBUGF  1, " [ESP+20]: %x\n",[ebx]
282
        add     ebx, 4
282
        add     ebx, 4
283
        call    .check_ESP
283
        call    .check_ESP
284
        test    eax, eax
284
        test    eax, eax
285
        jnz     .error_ESP
285
        jnz     .error_ESP
286
        DEBUGF  1, "K : [ESP+24]: %x",[ebx]
286
        DEBUGF  1, "K : [ESP+24]: %x",[ebx]
287
        add     ebx, 4
287
        add     ebx, 4
288
        call    .check_ESP
288
        call    .check_ESP
289
        test    eax, eax
289
        test    eax, eax
290
        jnz     .error_ESP
290
        jnz     .error_ESP
291
        DEBUGF  1, " [ESP+28]: %x",[ebx]
291
        DEBUGF  1, " [ESP+28]: %x",[ebx]
292
        add     ebx, 4
292
        add     ebx, 4
293
        call    .check_ESP
293
        call    .check_ESP
294
        test    eax, eax
294
        test    eax, eax
295
        jnz     .error_ESP
295
        jnz     .error_ESP
296
        DEBUGF  1, " [ESP+32]: %x\n",[ebx]
296
        DEBUGF  1, " [ESP+32]: %x\n",[ebx]
297
        pop     edx ecx ebx eax
297
        pop     edx ecx ebx eax
298
        ret
298
        ret
299
.error_ESP:
299
.error_ESP:
300
        pop     edx ecx ebx eax
300
        pop     edx ecx ebx eax
301
        DEBUGF  1, "\n"
301
        DEBUGF  1, "\n"
302
        DEBUGF  1, "K : Unexpected end of the stack\n"
302
        DEBUGF  1, "K : Unexpected end of the stack\n"
303
        ret
303
        ret
304
;--------------------------------------
304
;--------------------------------------
305
.check_ESP:
305
.check_ESP:
306
        push    ebx
306
        push    ebx
307
        shr     ebx, 12
307
        shr     ebx, 12
308
        mov     ecx, ebx
308
        mov     ecx, ebx
309
        shr     ecx, 10
309
        shr     ecx, 10
310
        mov     edx, [master_tab+ecx*4]
310
        mov     edx, [master_tab+ecx*4]
311
        test    edx, PG_MAP
311
        test    edx, PG_MAP
312
        jz      .fail             ;page table is not created
312
        jz      .fail             ;page table is not created
313
                                  ;incorrect address in the program
313
                                  ;incorrect address in the program
314
 
314
 
315
        mov     eax, [page_tabs+ebx*4]
315
        mov     eax, [page_tabs+ebx*4]
316
        test    eax, 2
316
        test    eax, 2
317
        jz      .fail             ;address not reserved for use. error
317
        jz      .fail             ;address not reserved for use. error
318
 
318
 
319
        pop     ebx
319
        pop     ebx
320
        xor     eax, eax
320
        xor     eax, eax
321
        ret
321
        ret
322
 
322
 
323
.fail:
323
.fail:
324
        pop     ebx
324
        pop     ebx
325
        xor     eax, eax
325
        xor     eax, eax
326
        dec     eax
326
        dec     eax
327
        ret
327
        ret
328
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
328
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
329
 
329
 
330
  restore  reg_ss
330
  restore  reg_ss
331
  restore  reg_esp3
331
  restore  reg_esp3
332
  restore  reg_eflags
332
  restore  reg_eflags
333
  restore  reg_cs
333
  restore  reg_cs
334
  restore  reg_eip
334
  restore  reg_eip
335
  restore  reg_eax
335
  restore  reg_eax
336
  restore  reg_ecx
336
  restore  reg_ecx
337
  restore  reg_edx
337
  restore  reg_edx
338
  restore  reg_ebx
338
  restore  reg_ebx
339
  restore  reg_esp0
339
  restore  reg_esp0
340
  restore  reg_ebp
340
  restore  reg_ebp
341
  restore  reg_esi
341
  restore  reg_esi
342
  restore  reg_edi
342
  restore  reg_edi
343
 
343
 
344
 
344
 
345
align 4
345
align 4
346
lock_application_table:
346
lock_application_table:
347
        push    eax ecx edx
347
        push    eax ecx edx
348
        mov     ecx, application_table_mutex
348
        mov     ecx, application_table_mutex
349
        call    mutex_lock
349
        call    mutex_lock
350
 
350
 
351
        mov     eax, [CURRENT_TASK]
351
        mov     eax, [CURRENT_TASK]
352
        shl     eax, 5
352
        shl     eax, 5
353
        add     eax, CURRENT_TASK+TASKDATA.pid
353
        add     eax, CURRENT_TASK+TASKDATA.pid
354
        mov     eax, [eax]
354
        mov     eax, [eax]
355
 
355
 
356
        mov     [application_table_owner], eax
356
        mov     [application_table_owner], eax
357
 
357
 
358
        pop     edx ecx eax
358
        pop     edx ecx eax
359
 
359
 
360
        ret
360
        ret
361
 
361
 
362
align 4
362
align 4
363
unlock_application_table:
363
unlock_application_table:
364
        push    eax ecx edx
364
        push    eax ecx edx
365
 
365
 
366
        mov     [application_table_owner], 0
366
        mov     [application_table_owner], 0
367
        mov     ecx, application_table_mutex
367
        mov     ecx, application_table_mutex
368
        call    mutex_unlock
368
        call    mutex_unlock
369
 
369
 
370
        pop     edx ecx eax
370
        pop     edx ecx eax
371
 
371
 
372
        ret
372
        ret
373
 
373
 
374
;  * eax = 64 - номер функции
374
;  * eax = 64 - номер функции
375
;  * ebx = 1 - единственная подфункция
375
;  * ebx = 1 - единственная подфункция
376
;  * ecx = новый размер памяти
376
;  * ecx = новый размер памяти
377
;Возвращаемое значение:
377
;Возвращаемое значение:
378
;  * eax = 0 - успешно
378
;  * eax = 0 - успешно
379
;  * eax = 1 - недостаточно памяти
379
;  * eax = 1 - недостаточно памяти
380
 
380
 
381
align 4
381
align 4
382
sys_resize_app_memory:
382
sys_resize_app_memory:
383
        ; ebx = 1 - resize
383
        ; ebx = 1 - resize
384
        ; ecx = new amount of memory
384
        ; ecx = new amount of memory
385
 
385
 
386
;        cmp    eax,1
386
;        cmp    eax,1
387
        dec     ebx
387
        dec     ebx
388
        jnz     .no_application_mem_resize
388
        jnz     .no_application_mem_resize
389
 
389
 
390
        mov     eax, [pg_data.pages_free]
390
        mov     eax, [pg_data.pages_free]
391
        shl     eax, 12
391
        shl     eax, 12
392
        cmp     eax, ecx
392
        cmp     eax, ecx
393
        jae     @f
393
        jae     @f
394
 
394
 
395
        xor     eax, eax
395
        xor     eax, eax
396
        inc     eax
396
        inc     eax
397
        jmp     .store_result
397
        jmp     .store_result
398
@@:
398
@@:
399
        stdcall new_mem_resize, ecx
399
        stdcall new_mem_resize, ecx
400
.store_result:
400
.store_result:
401
        mov     [esp+32], eax
401
        mov     [esp+32], eax
402
.no_application_mem_resize:
402
.no_application_mem_resize:
403
        ret
403
        ret
404
 
404
 
405
iglobal
405
iglobal
406
;  process_terminating  db 'K : Process - terminating',13,10,0
406
;  process_terminating  db 'K : Process - terminating',13,10,0
407
;  process_terminated   db 'K : Process - done',13,10,0
407
;  process_terminated   db 'K : Process - done',13,10,0
408
  msg_obj_destroy       db 'K : destroy app object',13,10,0
408
  msg_obj_destroy       db 'K : destroy app object',13,10,0
409
endg
409
endg
410
 
410
 
411
; param
411
; param
412
;  esi= slot
412
;  esi= slot
413
 
413
 
414
align 4
414
align 4
415
terminate: ; terminate application
415
terminate: ; terminate application
416
destroy_thread:
416
destroy_thread:
417
 
417
 
418
        .slot     equ esp+4             ;locals
418
        .slot     equ esp+4             ;locals
419
        .process  equ esp               ;ptr to parent process
419
        .process  equ esp               ;ptr to parent process
420
 
-
 
421
        xchg bx, bx
420
 
422
 
421
 
423
        push    esi                     ;save .slot
422
        push    esi                     ;save .slot
424
 
423
 
425
        shl     esi, 8
424
        shl     esi, 8
426
        mov     edx, [SLOT_BASE+esi+APPDATA.process]
425
        mov     edx, [SLOT_BASE+esi+APPDATA.process]
427
        test    edx, edx
426
        test    edx, edx
428
        jnz     @F
427
        jnz     @F
429
        pop     esi
428
        pop     esi
430
        shl     esi, 5
429
        shl     esi, 5
431
        mov     [CURRENT_TASK+esi+TASKDATA.state], 9
430
        mov     [CURRENT_TASK+esi+TASKDATA.state], 9
432
        ret
431
        ret
433
@@:
432
@@:
434
        push    edx                     ;save .process
433
        push    edx                     ;save .process
435
        lea     edx, [SLOT_BASE+esi]
434
        lea     edx, [SLOT_BASE+esi]
436
        call    scheduler_remove_thread
435
        call    scheduler_remove_thread
437
        call    lock_application_table
436
        call    lock_application_table
438
 
437
 
439
; if the process is in V86 mode...
438
; if the process is in V86 mode...
440
        mov     eax, [.slot]
439
        mov     eax, [.slot]
441
        shl     eax, 8
440
        shl     eax, 8
442
        mov     esi, [eax+SLOT_BASE+APPDATA.pl0_stack]
441
        mov     esi, [eax+SLOT_BASE+APPDATA.pl0_stack]
443
        add     esi, RING0_STACK_SIZE
442
        add     esi, RING0_STACK_SIZE
444
        cmp     [eax+SLOT_BASE+APPDATA.saved_esp0], esi
443
        cmp     [eax+SLOT_BASE+APPDATA.saved_esp0], esi
445
        jz      .nov86
444
        jz      .nov86
446
; ...it has page directory for V86 mode
445
; ...it has page directory for V86 mode
447
        mov     esi, [eax+SLOT_BASE+APPDATA.saved_esp0]
446
        mov     esi, [eax+SLOT_BASE+APPDATA.saved_esp0]
448
        mov     ecx, [esi+4]
447
        mov     ecx, [esi+4]
449
        mov     [eax+SLOT_BASE+APPDATA.process], ecx
448
        mov     [eax+SLOT_BASE+APPDATA.process], ecx
450
; ...and I/O permission map for V86 mode
449
; ...and I/O permission map for V86 mode
451
        mov     ecx, [esi+12]
450
        mov     ecx, [esi+12]
452
        mov     [eax+SLOT_BASE+APPDATA.io_map], ecx
451
        mov     [eax+SLOT_BASE+APPDATA.io_map], ecx
453
        mov     ecx, [esi+8]
452
        mov     ecx, [esi+8]
454
        mov     [eax+SLOT_BASE+APPDATA.io_map+4], ecx
453
        mov     [eax+SLOT_BASE+APPDATA.io_map+4], ecx
455
.nov86:
454
.nov86:
456
;destroy per-thread kerlen objects
455
;destroy per-thread kernel objects
457
        mov     esi, [.slot]
456
        mov     esi, [.slot]
458
        shl     esi, 8
457
        shl     esi, 8
459
        add     esi, SLOT_BASE+APP_OBJ_OFFSET
458
        add     esi, SLOT_BASE+APP_OBJ_OFFSET
460
@@:
459
@@:
461
        mov     eax, [esi+APPOBJ.fd]
460
        mov     eax, [esi+APPOBJ.fd]
462
        test    eax, eax
461
        test    eax, eax
463
        jz      @F
462
        jz      @F
464
 
463
 
465
        cmp     eax, esi
464
        cmp     eax, esi
466
        je      @F
465
        je      @F
467
 
466
 
468
        push    esi
467
        push    esi
469
        call    [eax+APPOBJ.destroy]
468
        call    [eax+APPOBJ.destroy]
470
           DEBUGF 1,"%s",msg_obj_destroy
469
           DEBUGF 1,"%s",msg_obj_destroy
471
        pop     esi
470
        pop     esi
472
        jmp     @B
471
        jmp     @B
473
@@:
472
@@:
474
        mov     esi, [.slot]
473
        mov     esi, [.slot]
475
        cmp     [fpu_owner], esi ; if user fpu last -> fpu user = 2
474
        cmp     [fpu_owner], esi ; if user fpu last -> fpu user = 2
476
        jne     @F
475
        jne     @F
477
 
476
 
478
        mov     [fpu_owner], 2
477
        mov     [fpu_owner], 2
479
        mov     eax, [256*2+SLOT_BASE+APPDATA.fpu_state]
478
        mov     eax, [256*2+SLOT_BASE+APPDATA.fpu_state]
480
        clts
479
        clts
481
        bt      [cpu_caps], CAPS_SSE
480
        bt      [cpu_caps], CAPS_SSE
482
        jnc     .no_SSE
481
        jnc     .no_SSE
483
        fxrstor [eax]
482
        fxrstor [eax]
484
        jmp     @F
483
        jmp     @F
485
.no_SSE:
484
.no_SSE:
486
        fnclex
485
        fnclex
487
        frstor  [eax]
486
        frstor  [eax]
488
@@:
487
@@:
489
 
488
 
490
        mov     [KEY_COUNT], byte 0    ; empty keyboard buffer
489
        mov     [KEY_COUNT], byte 0    ; empty keyboard buffer
491
        mov     [BTN_COUNT], byte 0    ; empty button buffer
490
        mov     [BTN_COUNT], byte 0    ; empty button buffer
492
 
491
 
493
 
492
 
494
; remove defined hotkeys
493
; remove defined hotkeys
495
        mov     eax, hotkey_list
494
        mov     eax, hotkey_list
496
.loop:
495
.loop:
497
        cmp     [eax+8], esi
496
        cmp     [eax+8], esi
498
        jnz     .cont
497
        jnz     .cont
499
        mov     ecx, [eax]
498
        mov     ecx, [eax]
500
        jecxz   @f
499
        jecxz   @f
501
        push    dword [eax+12]
500
        push    dword [eax+12]
502
        pop     dword [ecx+12]
501
        pop     dword [ecx+12]
503
@@:
502
@@:
504
        mov     ecx, [eax+12]
503
        mov     ecx, [eax+12]
505
        push    dword [eax]
504
        push    dword [eax]
506
        pop     dword [ecx]
505
        pop     dword [ecx]
507
        xor     ecx, ecx
506
        xor     ecx, ecx
508
        mov     [eax], ecx
507
        mov     [eax], ecx
509
        mov     [eax+4], ecx
508
        mov     [eax+4], ecx
510
        mov     [eax+8], ecx
509
        mov     [eax+8], ecx
511
        mov     [eax+12], ecx
510
        mov     [eax+12], ecx
512
.cont:
511
.cont:
513
        add     eax, 16
512
        add     eax, 16
514
        cmp     eax, hotkey_list+256*16
513
        cmp     eax, hotkey_list+256*16
515
        jb      .loop
514
        jb      .loop
516
; get process PID
515
; get process PID
517
        mov     eax, esi
516
        mov     eax, esi
518
        shl     eax, 5
517
        shl     eax, 5
519
        mov     eax, [eax+CURRENT_TASK+TASKDATA.pid]
518
        mov     eax, [eax+CURRENT_TASK+TASKDATA.pid]
520
; compare current lock input with process PID
519
; compare current lock input with process PID
521
        cmp     eax, [PID_lock_input]
520
        cmp     eax, [PID_lock_input]
522
        jne     @f
521
        jne     @f
523
 
522
 
524
        xor     eax, eax
523
        xor     eax, eax
525
        mov     [PID_lock_input], eax
524
        mov     [PID_lock_input], eax
526
@@:
525
@@:
527
; remove hotkeys in buffer
526
; remove hotkeys in buffer
528
        mov     eax, hotkey_buffer
527
        mov     eax, hotkey_buffer
529
.loop2:
528
.loop2:
530
        cmp     [eax], esi
529
        cmp     [eax], esi
531
        jnz     .cont2
530
        jnz     .cont2
532
        and     dword [eax+4], 0
531
        and     dword [eax+4], 0
533
        and     dword [eax], 0
532
        and     dword [eax], 0
534
.cont2:
533
.cont2:
535
        add     eax, 8
534
        add     eax, 8
536
        cmp     eax, hotkey_buffer+120*8
535
        cmp     eax, hotkey_buffer+120*8
537
        jb      .loop2
536
        jb      .loop2
538
 
537
 
539
        mov     ecx, esi          ; remove buttons
538
        mov     ecx, esi          ; remove buttons
540
  bnewba2:
539
  bnewba2:
541
        mov     edi, [BTN_ADDR]
540
        mov     edi, [BTN_ADDR]
542
        mov     eax, edi
541
        mov     eax, edi
543
        cld
542
        cld
544
        movzx   ebx, word [edi]
543
        movzx   ebx, word [edi]
545
        inc     bx
544
        inc     bx
546
  bnewba:
545
  bnewba:
547
        dec     bx
546
        dec     bx
548
        jz      bnmba
547
        jz      bnmba
549
        add     eax, 0x10
548
        add     eax, 0x10
550
        cmp     cx, [eax]
549
        cmp     cx, [eax]
551
        jnz     bnewba
550
        jnz     bnewba
552
        pusha
551
        pusha
553
        mov     ecx, ebx
552
        mov     ecx, ebx
554
        inc     ecx
553
        inc     ecx
555
        shl     ecx, 4
554
        shl     ecx, 4
556
        mov     ebx, eax
555
        mov     ebx, eax
557
        add     eax, 0x10
556
        add     eax, 0x10
558
        call    memmove
557
        call    memmove
559
        dec     dword [edi]
558
        dec     dword [edi]
560
        popa
559
        popa
561
        jmp     bnewba2
560
        jmp     bnewba2
562
  bnmba:
561
  bnmba:
563
 
562
 
564
        pusha   ; save window coordinates for window restoring
563
        pusha   ; save window coordinates for window restoring
565
        cld
564
        cld
566
        shl     esi, 5
565
        shl     esi, 5
567
        add     esi, window_data
566
        add     esi, window_data
568
        mov     eax, [esi+WDATA.box.left]
567
        mov     eax, [esi+WDATA.box.left]
569
        mov     [draw_limits.left], eax
568
        mov     [draw_limits.left], eax
570
        add     eax, [esi+WDATA.box.width]
569
        add     eax, [esi+WDATA.box.width]
571
        mov     [draw_limits.right], eax
570
        mov     [draw_limits.right], eax
572
        mov     eax, [esi+WDATA.box.top]
571
        mov     eax, [esi+WDATA.box.top]
573
        mov     [draw_limits.top], eax
572
        mov     [draw_limits.top], eax
574
        add     eax, [esi+WDATA.box.height]
573
        add     eax, [esi+WDATA.box.height]
575
        mov     [draw_limits.bottom], eax
574
        mov     [draw_limits.bottom], eax
576
 
575
 
577
        xor     eax, eax
576
        xor     eax, eax
578
        mov     [esi+WDATA.box.left], eax
577
        mov     [esi+WDATA.box.left], eax
579
        mov     [esi+WDATA.box.width], eax
578
        mov     [esi+WDATA.box.width], eax
580
        mov     [esi+WDATA.box.top], eax
579
        mov     [esi+WDATA.box.top], eax
581
        mov     [esi+WDATA.box.height], eax
580
        mov     [esi+WDATA.box.height], eax
582
        mov     [esi+WDATA.cl_workarea], eax
581
        mov     [esi+WDATA.cl_workarea], eax
583
        mov     [esi+WDATA.cl_titlebar], eax
582
        mov     [esi+WDATA.cl_titlebar], eax
584
        mov     [esi+WDATA.cl_frames], eax
583
        mov     [esi+WDATA.cl_frames], eax
585
        mov     dword [esi+WDATA.reserved], eax; clear all flags: wstate, redraw, wdrawn
584
        mov     dword [esi+WDATA.reserved], eax; clear all flags: wstate, redraw, wdrawn
586
        lea     edi, [esi-window_data+draw_data]
585
        lea     edi, [esi-window_data+draw_data]
587
        mov     ecx, 32/4
586
        mov     ecx, 32/4
588
        rep stosd
587
        rep stosd
589
        popa
588
        popa
590
 
589
 
591
; debuggee test
590
; debuggee test
592
        pushad
591
        pushad
593
        mov     edi, esi
592
        mov     edi, esi
594
        shl     edi, 5
593
        shl     edi, 5
595
        mov     eax, [SLOT_BASE+edi*8+APPDATA.debugger_slot]
594
        mov     eax, [SLOT_BASE+edi*8+APPDATA.debugger_slot]
596
        test    eax, eax
595
        test    eax, eax
597
        jz      .nodebug
596
        jz      .nodebug
598
        movi    ecx, 8
597
        movi    ecx, 8
599
        push    dword [CURRENT_TASK+edi+TASKDATA.pid]; PID
598
        push    dword [CURRENT_TASK+edi+TASKDATA.pid]; PID
600
        push    2
599
        push    2
601
        call    debugger_notify
600
        call    debugger_notify
602
        pop     ecx
601
        pop     ecx
603
        pop     ecx
602
        pop     ecx
604
.nodebug:
603
.nodebug:
605
        popad
604
        popad
606
 
605
 
607
        mov     ebx, [.slot]
606
        mov     ebx, [.slot]
608
        shl     ebx, 8
607
        shl     ebx, 8
609
        push    ebx
608
        push    ebx
610
        mov     ebx, [SLOT_BASE+ebx+APPDATA.pl0_stack]
609
        mov     ebx, [SLOT_BASE+ebx+APPDATA.pl0_stack]
611
 
610
 
612
        stdcall kernel_free, ebx
611
        stdcall kernel_free, ebx
613
 
612
 
614
        pop     ebx
613
        pop     ebx
615
        mov     ebx, [SLOT_BASE+ebx+APPDATA.cur_dir]
614
        mov     ebx, [SLOT_BASE+ebx+APPDATA.cur_dir]
616
        stdcall kernel_free, ebx
615
        stdcall kernel_free, ebx
617
 
616
 
618
        mov     edi, [.slot]
617
        mov     edi, [.slot]
619
        shl     edi, 8
618
        shl     edi, 8
620
        add     edi, SLOT_BASE
619
        add     edi, SLOT_BASE
621
 
620
 
622
        mov     eax, [edi+APPDATA.io_map]
621
        mov     eax, [edi+APPDATA.io_map]
623
        cmp     eax, [SLOT_BASE+256+APPDATA.io_map]
622
        cmp     eax, [SLOT_BASE+256+APPDATA.io_map]
624
        je      @F
623
        je      @F
625
        call    free_page
624
        call    free_page
626
@@:
625
@@:
627
        mov     eax, [edi+APPDATA.io_map+4]
626
        mov     eax, [edi+APPDATA.io_map+4]
628
        cmp     eax, [SLOT_BASE+256+APPDATA.io_map+4]
627
        cmp     eax, [SLOT_BASE+256+APPDATA.io_map+4]
629
        je      @F
628
        je      @F
630
        call    free_page
629
        call    free_page
631
@@:
630
@@:
632
        lea     ebx, [edi+APPDATA.list]
631
        lea     ebx, [edi+APPDATA.list]
633
        list_del ebx                    ;destroys edx, ecx
632
        list_del ebx                    ;destroys edx, ecx
634
 
633
 
635
        mov     eax, 0x20202020
634
        mov     eax, 0x20202020
636
        stosd
635
        stosd
637
        stosd
636
        stosd
638
        stosd
637
        stosd
639
        mov     ecx, 244/4
638
        mov     ecx, 244/4
640
        xor     eax, eax
639
        xor     eax, eax
641
        rep stosd
640
        rep stosd
642
 
641
 
643
  ; activate window
642
  ; activate window
644
        movzx   eax, word [WIN_STACK + esi*2]
643
        movzx   eax, word [WIN_STACK + esi*2]
645
        cmp     eax, [TASK_COUNT]
644
        cmp     eax, [TASK_COUNT]
646
        jne     .dont_activate
645
        jne     .dont_activate
647
        pushad
646
        pushad
648
 .check_next_window:
647
 .check_next_window:
649
        dec     eax
648
        dec     eax
650
        cmp     eax, 1
649
        cmp     eax, 1
651
        jbe     .nothing_to_activate
650
        jbe     .nothing_to_activate
652
        lea     esi, [WIN_POS+eax*2]
651
        lea     esi, [WIN_POS+eax*2]
653
        movzx   edi, word [esi]              ; edi = process
652
        movzx   edi, word [esi]              ; edi = process
654
        shl     edi, 5
653
        shl     edi, 5
655
        cmp     [CURRENT_TASK + edi + TASKDATA.state], byte 9 ; skip dead slots
654
        cmp     [CURRENT_TASK + edi + TASKDATA.state], byte 9 ; skip dead slots
656
        je      .check_next_window
655
        je      .check_next_window
657
        add     edi, window_data
656
        add     edi, window_data
658
; \begin{diamond}[19.09.2006]
657
; \begin{diamond}[19.09.2006]
659
; skip minimized windows
658
; skip minimized windows
660
        test    [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
659
        test    [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
661
        jnz     .check_next_window
660
        jnz     .check_next_window
662
; \end{diamond}
661
; \end{diamond}
663
        call    waredraw
662
        call    waredraw
664
 .nothing_to_activate:
663
 .nothing_to_activate:
665
        popad
664
        popad
666
 .dont_activate:
665
 .dont_activate:
667
 
666
 
668
        push    esi     ; remove hd1 & cd & flp reservation
667
        push    esi     ; remove hd1 & cd & flp reservation
669
        shl     esi, 5
668
        shl     esi, 5
670
        mov     esi, [esi+CURRENT_TASK+TASKDATA.pid]
669
        mov     esi, [esi+CURRENT_TASK+TASKDATA.pid]
671
        cmp     [cd_status], esi
670
        cmp     [cd_status], esi
672
        jnz     @f
671
        jnz     @f
673
        call    free_cd_channel
672
        call    free_cd_channel
674
        and     [cd_status], 0
673
        and     [cd_status], 0
675
@@:
674
@@:
676
        pop     esi
675
        pop     esi
677
        cmp     [bgrlockpid], esi
676
        cmp     [bgrlockpid], esi
678
        jnz     @f
677
        jnz     @f
679
        and     [bgrlockpid], 0
678
        and     [bgrlockpid], 0
680
        and     [bgrlock], 0
679
        and     [bgrlock], 0
681
@@:
680
@@:
682
 
681
 
683
        pusha                 ; remove all port reservations
682
        pusha                 ; remove all port reservations
684
        mov     edx, esi
683
        mov     edx, esi
685
        shl     edx, 5
684
        shl     edx, 5
686
        add     edx, CURRENT_TASK
685
        add     edx, CURRENT_TASK
687
        mov     edx, [edx+TASKDATA.pid]
686
        mov     edx, [edx+TASKDATA.pid]
688
 
687
 
689
  rmpr0:
688
  rmpr0:
690
 
689
 
691
        mov     esi, [RESERVED_PORTS]
690
        mov     esi, [RESERVED_PORTS]
692
 
691
 
693
        test    esi, esi
692
        test    esi, esi
694
        jz      rmpr9
693
        jz      rmpr9
695
 
694
 
696
  rmpr3:
695
  rmpr3:
697
 
696
 
698
        mov     edi, esi
697
        mov     edi, esi
699
        shl     edi, 4
698
        shl     edi, 4
700
        add     edi, RESERVED_PORTS
699
        add     edi, RESERVED_PORTS
701
 
700
 
702
        cmp     edx, [edi]
701
        cmp     edx, [edi]
703
        je      rmpr4
702
        je      rmpr4
704
 
703
 
705
        dec     esi
704
        dec     esi
706
        jnz     rmpr3
705
        jnz     rmpr3
707
 
706
 
708
        jmp     rmpr9
707
        jmp     rmpr9
709
 
708
 
710
  rmpr4:
709
  rmpr4:
711
 
710
 
712
        mov     ecx, 256
711
        mov     ecx, 256
713
        sub     ecx, esi
712
        sub     ecx, esi
714
        shl     ecx, 4
713
        shl     ecx, 4
715
 
714
 
716
        mov     esi, edi
715
        mov     esi, edi
717
        add     esi, 16
716
        add     esi, 16
718
        cld
717
        cld
719
        rep movsb
718
        rep movsb
720
 
719
 
721
        dec     dword [RESERVED_PORTS]
720
        dec     dword [RESERVED_PORTS]
722
 
721
 
723
        jmp     rmpr0
722
        jmp     rmpr0
724
 
723
 
725
  rmpr9:
724
  rmpr9:
726
 
725
 
727
        popa
726
        popa
728
        mov     edi, esi ; do not run this process slot
727
        mov     edi, esi ; do not run this process slot
729
        shl     edi, 5
728
        shl     edi, 5
730
        mov     [edi+CURRENT_TASK + TASKDATA.state], byte 9
729
        mov     [edi+CURRENT_TASK + TASKDATA.state], byte 9
731
; debugger test - terminate all debuggees
730
; debugger test - terminate all debuggees
732
        mov     eax, 2
731
        mov     eax, 2
733
        mov     ecx, SLOT_BASE+2*0x100+APPDATA.debugger_slot
732
        mov     ecx, SLOT_BASE+2*0x100+APPDATA.debugger_slot
734
.xd0:
733
.xd0:
735
        cmp     eax, [TASK_COUNT]
734
        cmp     eax, [TASK_COUNT]
736
        ja      .xd1
735
        ja      .xd1
737
        cmp     dword [ecx], esi
736
        cmp     dword [ecx], esi
738
        jnz     @f
737
        jnz     @f
739
        and     dword [ecx], 0
738
        and     dword [ecx], 0
740
        pushad
739
        pushad
741
        xchg    eax, ecx
740
        xchg    eax, ecx
742
        mov     ebx, 2
741
        mov     ebx, 2
743
        call    sys_system
742
        call    sys_system
744
        popad
743
        popad
745
@@:
744
@@:
746
        inc     eax
745
        inc     eax
747
        add     ecx, 0x100
746
        add     ecx, 0x100
748
        jmp     .xd0
747
        jmp     .xd0
749
.xd1:
748
.xd1:
750
;release slot
749
;release slot
751
 
-
 
752
        xchg bx, bx
750
 
753
 
751
 
754
        bts     [thr_slot_map], esi
752
        bts     [thr_slot_map], esi
755
 
753
 
756
        mov     ecx, [.process]
754
        mov     ecx, [.process]
757
        lea     eax, [ecx+PROC.thr_list]
755
        lea     eax, [ecx+PROC.thr_list]
758
        cmp     eax, [eax+LHEAD.next]
756
        cmp     eax, [eax+LHEAD.next]
759
        jne     @F
757
        jne     @F
760
 
758
 
761
        call    destroy_process.internal
759
        call    destroy_process.internal
762
@@:
760
@@:
763
        sti     ; .. and life goes on
761
        sti     ; .. and life goes on
764
 
762
 
765
        mov     eax, [draw_limits.left]
763
        mov     eax, [draw_limits.left]
766
        mov     ebx, [draw_limits.top]
764
        mov     ebx, [draw_limits.top]
767
        mov     ecx, [draw_limits.right]
765
        mov     ecx, [draw_limits.right]
768
        mov     edx, [draw_limits.bottom]
766
        mov     edx, [draw_limits.bottom]
769
        call    calculatescreen
767
        call    calculatescreen
770
        xor     eax, eax
768
        xor     eax, eax
771
        xor     esi, esi
769
        xor     esi, esi
772
        call    redrawscreen
770
        call    redrawscreen
773
 
771
 
774
        call    unlock_application_table
772
        call    unlock_application_table
775
    ;mov   esi,process_terminated
773
    ;mov   esi,process_terminated
776
    ;call  sys_msg_board_str
774
    ;call  sys_msg_board_str
777
        add     esp, 8
775
        add     esp, 8
778
        ret
776
        ret
779
restore .slot
777
restore .slot
780
restore .process
778
restore .process
781
 
779
 
782
; Three following procedures are used to guarantee that
780
; Three following procedures are used to guarantee that
783
; some part of kernel code will not be terminated from outside
781
; some part of kernel code will not be terminated from outside
784
; while it is running.
782
; while it is running.
785
; Note: they do not protect a thread from terminating due to errors inside
783
; Note: they do not protect a thread from terminating due to errors inside
786
; the thread; accessing a nonexisting memory would still terminate it.
784
; the thread; accessing a nonexisting memory would still terminate it.
787
 
785
 
788
; First two procedures must be used in pair by thread-to-be-protected
786
; First two procedures must be used in pair by thread-to-be-protected
789
; to signal the beginning and the end of an important part.
787
; to signal the beginning and the end of an important part.
790
; It is OK to have nested areas.
788
; It is OK to have nested areas.
791
 
789
 
792
; The last procedure must be used by outside wanna-be-terminators;
790
; The last procedure must be used by outside wanna-be-terminators;
793
; if it is safe to terminate the given thread immediately, it returns eax=1;
791
; if it is safe to terminate the given thread immediately, it returns eax=1;
794
; otherwise, it returns eax=0 and notifies the target thread that it should
792
; otherwise, it returns eax=0 and notifies the target thread that it should
795
; terminate itself when leaving a critical area (the last critical area if
793
; terminate itself when leaving a critical area (the last critical area if
796
; they are nested).
794
; they are nested).
797
 
795
 
798
; Implementation. Those procedures use one dword in APPDATA for the thread,
796
; Implementation. Those procedures use one dword in APPDATA for the thread,
799
; APPDATA.terminate_protection.
797
; APPDATA.terminate_protection.
800
; * The upper bit is 1 during normal operations and 0 when terminate is requested.
798
; * The upper bit is 1 during normal operations and 0 when terminate is requested.
801
; * Other bits form a number = depth of critical regions,
799
; * Other bits form a number = depth of critical regions,
802
;   plus 1 if the upper bit is 1.
800
;   plus 1 if the upper bit is 1.
803
; * When this dword goes to zero, the thread should be destructed,
801
; * When this dword goes to zero, the thread should be destructed,
804
;   and the procedure in which it happened becomes responsible for destruction.
802
;   and the procedure in which it happened becomes responsible for destruction.
805
 
803
 
806
; Enter critical area. Called by thread which wants to be protected.
804
; Enter critical area. Called by thread which wants to be protected.
807
proc protect_from_terminate
805
proc protect_from_terminate
808
        mov     edx, [current_slot]
806
        mov     edx, [current_slot]
809
; Atomically increment depth of critical areas and get the old value.
807
; Atomically increment depth of critical areas and get the old value.
810
        mov     eax, 1
808
        mov     eax, 1
811
        lock xadd [edx+APPDATA.terminate_protection], eax
809
        lock xadd [edx+APPDATA.terminate_protection], eax
812
; If the old value was zero, somebody has started to terminate us,
810
; If the old value was zero, somebody has started to terminate us,
813
; so we are destructing and cannot do anything protected.
811
; so we are destructing and cannot do anything protected.
814
; Otherwise, return to the caller.
812
; Otherwise, return to the caller.
815
        test    eax, eax
813
        test    eax, eax
816
        jz      @f
814
        jz      @f
817
        ret
815
        ret
818
@@:
816
@@:
819
; Wait for somebody to finish us.
817
; Wait for somebody to finish us.
820
        call    change_task
818
        call    change_task
821
        jmp     @b
819
        jmp     @b
822
endp
820
endp
823
 
821
 
824
; Leave critical area. Called by thread which wants to be protected.
822
; Leave critical area. Called by thread which wants to be protected.
825
proc unprotect_from_terminate
823
proc unprotect_from_terminate
826
        mov     edx, [current_slot]
824
        mov     edx, [current_slot]
827
; Atomically decrement depth of critical areas.
825
; Atomically decrement depth of critical areas.
828
        lock dec [edx+APPDATA.terminate_protection]
826
        lock dec [edx+APPDATA.terminate_protection]
829
; If the result of decrement is zero, somebody has requested termination,
827
; If the result of decrement is zero, somebody has requested termination,
830
; but at that moment we were inside a critical area; terminate now.
828
; but at that moment we were inside a critical area; terminate now.
831
        jz      sys_end
829
        jz      sys_end
832
; Otherwise, return to the caller.
830
; Otherwise, return to the caller.
833
        ret
831
        ret
834
endp
832
endp
835
 
833
 
836
; Request termination of thread identified by edx = SLOT_BASE + slot*256.
834
; Request termination of thread identified by edx = SLOT_BASE + slot*256.
837
; Called by anyone.
835
; Called by anyone.
838
proc request_terminate
836
proc request_terminate
839
        xor     eax, eax        ; set return value
837
        xor     eax, eax        ; set return value
840
; Atomically clear the upper bit. If it was already zero, then
838
; Atomically clear the upper bit. If it was already zero, then
841
; somebody has requested termination before us, so just exit.
839
; somebody has requested termination before us, so just exit.
842
        lock btr [edx+APPDATA.terminate_protection], 31
840
        lock btr [edx+APPDATA.terminate_protection], 31
843
        jnc     .unsafe
841
        jnc     .unsafe
844
; Atomically decrement depth of critical areas.
842
; Atomically decrement depth of critical areas.
845
        lock dec [edx+APPDATA.terminate_protection]
843
        lock dec [edx+APPDATA.terminate_protection]
846
; If the result of decrement is nonzero, the target thread is inside a
844
; If the result of decrement is nonzero, the target thread is inside a
847
; critical area; leave termination to leaving that area.
845
; critical area; leave termination to leaving that area.
848
        jnz     .unsafe
846
        jnz     .unsafe
849
; Otherwise, it is safe to kill the target now and the caller is responsible
847
; Otherwise, it is safe to kill the target now and the caller is responsible
850
; for this. Return eax=1.
848
; for this. Return eax=1.
851
        inc     eax
849
        inc     eax
852
.unsafe:
850
.unsafe:
853
        ret
851
        ret
854
endp
852
endp