Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
7389 theonlymir 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
; Hot Angles ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4
; Compile with FASM
5
; Version 0.1: Sep 18, 2018
6
 
7
; Copyright (c) 2018, Efremenkov Sergey aka TheOnlyMirage
8
; All rights reserved.
9
; Redistribution and use in source and binary forms, with or without modification,
10
; are permitted provided that the following conditions are met:
11
;    * Redistributions of source code must retain the above copyright notice, this
12
;    list of conditions and the following disclaimer.
13
;    * Redistributions in binary form must reproduce the above copyright  notice,
14
;    this list of conditions and the following disclaimer in the documentation and/or
15
;    other materials provided with the distribution.
16
;    * Neither the name of the  nor the names of its contributors may
17
;    be used to endorse or promote products derived from this software without
18
;    specific prior written permission.
19
 
20
; THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
21
; INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
22
; PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23
; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24
; OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25
; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
; --------------------------------------------------------------------------------------
27
 
28
format binary as "" ;"kex"
29
use32
30
org 0x0    ; базовый адрес размещения кода, всегда 0x0
31
 
32
UNLOCKd = 0
33
LOCKd = 1
34
 
35
; заголовок
36
db 'MENUET01'     ;магический идентификатор
37
dd 0x01           ;версия
38
dd START_DEBUG          ;адрес точки старта программы
39
dd I_END          ;адрес конца, по факту размер файла программы
40
dd 0x100000       ;требуемое кол-во памяти для загрузки программы
41
dd 0x7fff0        ;начальное значение регистра esp - адрес конца области стэка так как стэк растет в сторону меньших адресов
42
dd 0, 0           ;адрес строки параметров и адрес строки пути исполняемого файла
43
 
44
 
45
include '../../macros.inc'
46
 
47
START_DEBUG:
48
   call copyKill         ;простейшая защита от повторного запуска
49
   mcall  68, 11         ;инициализация кучи
50
   call loadConfig       ;загружаем конфигурацию приложения
51
   mov ebx, 00000100000000000000000000100000b ;подписываемся на интересные нам события
52
   mcall 40
53
 
54
START:
55
  mov     eax, 10                 ; function 10 : wait until event
56
  mcall                           ; event type is returned in eax
57
 
58
  cmp   eax, 6           ;обработка перемещений и нажатия мыши
59
  je    mouse
60
 
61
  jmp START
62
 
63
mouse:
64
  ;основной цикл программы
65
  call get_mouse_pos ;получаем текущие координаты мыши
66
 
67
  cmp eax, 0 ;левый верхний угол
68
  jne @f
69
  ; -- здесь вызываем соотв. вызов для левого верхнего угла  (X=0, Y=0)
70
  push ecx
71
  mov ecx, 0
72
  call run_command
73
  pop ecx
74
 
75
  jmp START ;finish
76
@@:
77
  call get_screen_size ;иначе обновляем размеры экрана
78
 
79
  cmp ax, word[screen.height]    ;Ymouse = Yscreen ?
80
  je Ytrue
81
  ;если Y не равны, то нас интересует Y=0 и X=ScreenWidth (правый верхний угол)
82
 
83
  cmp ax, 0
84
  jne unlockend
85
  shr eax, 16
86
  cmp ax, word[screen.width]
87
  jne unlockend
88
  ; -- здесь вызываем для правого верхенего угла
89
  push ecx
90
  mov ecx, 2
91
  call run_command
92
  pop ecx
93
 
94
  jmp START
95
Ytrue:
96
  ;если Y равны, то нас интересует X=0 (левый нижний угол) или X=ScreenWidth (правый нижний)
97
  shr eax, 16
98
  cmp ax, 0
99
  jne @f
100
  ; -- X=0, Y = Height  (левый нижний угол)
101
  push ecx
102
  mov ecx, 1
103
  call run_command
104
  pop ecx
105
  jmp START
106
@@:
107
  cmp ax, word[screen.width]
108
  jne unlockend
109
  ; -- (правый нижний угол)
110
  push ecx
111
  mov ecx, 3
112
  call run_command
113
  pop ecx
114
 
115
  jmp START
116
 
117
unlockend:
118
  mov byte[state], UNLOCKd
119
  jmp START
120
 
121
 
122
;структурка данных для хранения параметров экрана
123
screen:
124
   .width  dw 0
125
   .height dw 0
126
;получить размер экрана
127
get_screen_size:
128
   push eax
129
   mcall 14
130
   ;теперь в eax = [xsize]*65536 + [ysize]
131
   ;mov dword[screen], eax
132
   mov word[screen.height], ax
133
   shr eax, 16
134
   mov word[screen.width], ax
135
   pop eax
136
   ret
137
 
138
 
139
;получить позицию мыши
140
get_mouse_pos:
141
   ;push eax
142
   push ebx
143
   mcall 37, 0
144
   pop ebx
145
   ;pop eax
146
   ret
147
 
148
 
149
;запуск приложения: ecx - активный угол: lu=0, ld=1, ru=2, rd=3
150
run_command:
151
   cmp byte[state], UNLOCKd
152
   jne run_command.end
153
 
154
   push eax
155
   push ebx
156
   push ecx
157
 
158
 
159
   cmp ecx, 0
160
   jne @f
161
   mov eax, dword[newData.lu] ;testData.lu
162
   mov dword[struct70.path_adr], eax
163
   jmp .end_set_path
164
@@:
165
   cmp ecx, 1
166
   jne @f
167
   mov eax, dword[newData.ld]
168
   mov dword[struct70.path_adr], eax
169
   jmp .end_set_path
170
@@:
171
   cmp ecx, 2
172
   jne @f
173
   mov eax, dword[newData.ru]
174
   mov dword[struct70.path_adr], eax
175
   jmp .end_set_path
176
@@:
177
   cmp ecx, 3
178
   jne .end_set_path
179
   mov eax, dword[newData.rd]
180
   mov dword[struct70.path_adr], eax
181
   jmp .end_set_path
182
.end_set_path:
183
 
184
   ;параметры
185
   ;mov dword[struct.adr],
186
 
187
;этот код заменить - если адрес 0, то ничего не делать
188
   cmp dword[struct70.path_adr], 0
189
   jne .next
190
   mov eax, testData.ld    ;
191
   mov dword[struct70.path_adr], eax
192
.next:
193
;конец кода для замены
194
 
195
   mcall 70, struct70
196
   mov byte[state], LOCKd
197
 
198
   pop ecx
199
   pop ebx
200
   pop eax
201
.end:
202
   ret
203
 
204
struct70: ;Формат информационной структуры
205
  .func       dd 7 ; номер подфункции
206
  .mask       dd 0
207
  .param_adr  dd 0 ; указатель на ASCIIZ-строку с параметрами
208
  .other      dd 0, 0
209
  .path       db 0 ; "/rd/1/TINYPAD",0 ; путь
210
  .path_adr   dd 0 ;testData.lu ;0
211
 
212
 
213
state: db 0 ; 0=unlock, 1=lock
214
 
215
testData:
216
  .lu db '/rd/1/SHELL', 0
217
  .ld db '/rd/1/RUN', 0
218
  .ru db "/rd/1/TINYPAD", 0
219
  .rd db '/rd/1/File Managers/EOLITE', 0
220
 
221
newData:  ;табличка адресов командных строк
222
  .lu dd 0
223
  .ld dd 0
224
  .ru dd 0
225
  .rd dd 0
226
newDataEnd:
227
 
228
;имя конфигурационного файла
229
fileName: db 'SETTINGS/HOTANGLES.CFG', 0  ;'ha.cfg', 0
230
 
231
loadConfig:
232
   push eax
233
   push ebx
234
   push ecx
235
   push edx
236
   mcall 68, 27, fileName   ;загружаем конфигурационный файл в ОЗУ
237
   cmp eax, 0
238
   je loadConfig.exit       ;если файла конфигурации нет, то завершаем работу приложения
239
   ;иначе данные загружены в ОЗУ, размер в edx
240
   cmp edx, 0               ;если файл пуст, в нём нет данных, то завершаем работу
241
   je loadConfig.exit
242
 
243
   add edx, eax             ;иначе кладём в edx - адрес конца файла
244
 
245
   cmp byte[eax], 121 ;'y'  ;если параметр активности приложения имеет статус: не активно
246
   jne loadConfig.exit      ;то завершаем работу приложения
247
 
248
   push edi
249
   push esi
250
   ; сохраняем в edi указатель на начало таблицы адресов наших команд
251
   mov edi, newData
252
   ; сохраняем адреса строк и добавляем 0 в конце
253
   mov esi, eax
254
.block:
255
   inc esi
256
   cmp byte[esi], 10         ;если очередной код символа 10 или 13, то пропускаем символы
257
   je loadConfig.propusk     ;до первого отличного от них
258
   cmp byte[esi], 13
259
   je loadConfig.propusk
260
 
261
   ; символ отличен от переноса строки и возврата каретки - запоминаем его
262
   mov dword[edi], esi
263
   add edi, 4
264
 
265
   ;идём до конца этой строки: пока не встретим очередной 10, 13, 0 или file end
266
.while:
267
   inc esi
268
   cmp esi, edx           ;тут будет проблема - тк файл закончился, а нуля не было !!! исправить
269
   jae loadConfig.fileend
270
   cmp byte[esi], 10
271
   je loadConfig.ura
272
   cmp byte[esi], 0
273
   je loadConfig.ura
274
   cmp byte[esi], 13
275
   jne loadConfig.while
276
.ura:
277
   mov byte[esi], 0
278
 
279
   cmp edi, newDataEnd ;newData.end      ;если вся таблица адресов заполнена, то выходим из цикла
280
   jb loadConfig.block
281
.fileend:
282
 
283
   pop esi
284
   pop edi
285
 
286
   jmp loadConfig.end
287
 
288
.propusk:
289
   mov byte[esi], 0
290
   jmp loadConfig.block
291
.exit:
292
   pop edx
293
   pop ecx
294
   pop ebx
295
   pop eax
296
   mcall -1 ;закрыть эту программу
297
.end:
298
   pop edx
299
   pop ecx
300
   pop ebx
301
   pop eax
302
   ret
303
 
304
 
305
 
306
 
307
;Вынести код ниже в отдельный общий модуль
308
selfName db '@HOTANGLES',0
309
selfNameSize = 10 ;до 11 byte
310
;
311
compareBytes:
312
   push edi esi ecx ebx
313
   mov eax, 0 ;xor eax, eax
314
   mov ecx, selfNameSize    ;max размер строк 11
315
@@:
316
   mov bl, byte[edi]
317
   cmp bl, byte[esi]
318
   jne compareBytes.no
319
   inc edi
320
   inc esi
321
   cmp ecx, 0
322
   je @f
323
   dec ecx
324
   jmp @b
325
.no:
326
   mov eax, 1
327
@@:
328
   pop ebx ecx esi edi
329
   ret
330
;
331
slotMax dd 0
332
selfPID dd 0
333
buf db 1024 dup(0)
334
copyKill:
335
   push eax ebx ecx esi edi
336
 
337
   ;сперва прочтём свою информацию
338
   mcall 9, buf, -1
339
   mov eax, dword[buf+30]
340
   mov dword[selfPID], eax
341
 
342
   ;указатели, которые никогда не меняются:
343
   mov esi, selfName       ;первая строка - имя текущего приложения
344
   mov edi, buf            ;вторая строка - имя текущего слота
345
   add edi, 10
346
 
347
   mov ecx, 1
348
@@:
349
   mcall 9, buf, ecx
350
   mov dword[slotMax], eax
351
 
352
   ;если это мы сами, то пропускаем проверку
353
   mov eax, dword[buf+30]
354
   cmp eax, dword[selfPID]
355
   je copyKill.propusk
356
 
357
   call compareBytes   ;сравниваем 11 байт строк, результат в eax
358
 
359
   cmp eax, 0
360
   je copyKill.selfKill
361
 
362
.propusk:
363
   inc ecx
364
   cmp ecx, dword[slotMax]
365
   ja @f
366
   jmp @b
367
 
368
.selfKill:
369
   pop edi esi ecx ebx eax
370
   mcall -1
371
   ret
372
@@:
373
   pop edi esi ecx ebx eax
374
   ret
375
 
376
 
377
 
378
I_END: