1,16 → 1,11 |
;****************************************************************************** |
; MAIN MENU |
;****************************************************************************** |
; last update: 22/03/2012 |
; changed by: Marat Zakiyanov aka Mario79, aka Mario |
; changes: Global optimization! The program uses |
; only 32 KB of memory instead of 128 kb is now. |
;------------------------------------------------------------------------------ |
; last update: 19/09/2011 |
; changed by: Marat Zakiyanov aka Mario79, aka Mario |
; changes: Checking for program exist to memory |
; Added processing of keys: left and right arrow |
;------------------------------------------------------------------------------ |
;--------------------------------------------------------------------- |
; MAIN MENU by lisovin@26.ru |
; Some parts of code rewritten by Ivan Poddubny <ivan-yar@bk.ru> |
; |
25,53 → 20,34 |
PANEL_HEIGHT = 20 |
MENU_BOTTON_X_POS = 10 |
MENU_BOTTON_X_SIZE = 60 |
;------------------------------------------------------------------------------ |
|
use32 |
org 0x0 |
|
db 'MENUET01' ; 8 byte id |
dd 0x01 ; header version |
dd START ; start of code |
dd IM_END ; size of image |
dd mem_end ; memory for app |
dd stack_area ; esp |
dd 0x0 ; boot parameters |
dd 0x0 ; path |
;------------------------------------------------------------------------------ |
dd I_END ; size of image |
dd 0x20000 ; memory for app |
dd 0x20000 ; esp |
dd 0x0,0x0 ; I_Param , I_Icon |
;****************************************************************************** |
;include "DEBUG.INC" ; debug macros |
;------------------------------------------------------------------------------ |
align 4 |
START: ; start of execution |
mcall 68,11 |
call program_exist |
mcall 14 |
mov [screen_size],eax |
|
mcall 48,3,sc,sizeof.system_colors ; load system colors |
|
; get size of file MENU.DAT |
mcall 70,fileinfo |
test eax,eax |
mcall 70,fileinfo ; load MENU.DAT |
test eax,eax ; error ? |
jz @f |
cmp eax,6 |
jnz close |
; get memory for MENU.DAT |
mov ecx,[procinfo+32] |
mov [fileinfo.size],ecx |
mcall 68,12 |
mov [fileinfo.return],eax |
mcall 68 |
mov [menu_data],eax |
; load MENU.DAT |
mov [fileinfo],dword 0 |
mcall 70,fileinfo |
test eax,eax |
jnz close |
|
@@: |
test ebx,ebx ; length = 0 ? |
jz close |
mov ecx,ebx |
mov edi,[fileinfo.return] ;mem_end |
;-------------------------------------- |
align 4 |
mov edi,mem_end |
newsearch: |
mov al,'#' |
cld |
83,31 → 59,24 |
jnz .number |
cmp al,'#' |
je search_end |
;-------------------------------------- |
align 4 |
.number: |
shl ebx,4 |
add ebx,[menu_data] ; pointer to process table |
add ebx,menu_data ; pointer to process table |
mov [ebx],edi |
inc [processes] |
jmp newsearch |
;-------------------------------------- |
align 4 |
;--------------------------------------------------------------------- |
search_end: |
mov [end_pointer],edi |
mov ebx,[processes] |
dec ebx |
shl ebx,4 |
add ebx,[menu_data] |
;-------------------------------------- |
align 4 |
add ebx,menu_data |
newprocess: |
xor edx,edx |
mov ecx,edi |
sub ecx,[ebx] |
mov al,10 |
;-------------------------------------- |
align 4 |
newsearch1: |
std |
repne scasb |
117,54 → 86,35 |
jne newsearch1 |
inc edx |
jmp newsearch1 |
;-------------------------------------- |
align 4 |
;--------------------------------------------------------------------- |
endprocess: |
mov esi,ebx |
add esi,4 |
dec edx |
mov [esi],dl |
cmp ebx,[menu_data] |
cmp ebx,menu_data |
jbe search_end1 |
sub ebx,16 |
jmp newprocess |
;-------------------------------------- |
align 4 |
;--------------------------------------------------------------------- |
search_end1: |
mcall 14 |
sub ax,20 |
mov ebx,[menu_data] |
mov [ebx + y_end],ax |
mov [ebx + x_start],5 |
mov al,[ebx + rows] |
mov [ebx + cur_sel],al ; clear selection |
mov [ebx + prev_sel],al |
mov [menu_data + y_end],ax |
mov [menu_data + x_start],5 |
mov al,[menu_data + rows] |
mov [menu_data + cur_sel],al ; clear selection |
mov [menu_data + prev_sel],al |
mov [buffer],0 |
;------------------------------------------------------------------------------ |
align 4 |
thread: |
mov ebp,esp |
sub ebp,0x1000 |
cmp ebp,0x2000 ; if this is first started thread |
ja @f |
xor ebp,ebp ; not free area |
;-------------------------------------- |
align 4 |
@@: |
mov eax,[buffer] ; identifier |
shl eax,4 |
add eax,[menu_data] |
add eax,menu_data |
mov edi,eax |
mcall 40,100111b ; mouse + button + key + redraw |
;------------------------------------------------------------------------------ |
align 4 |
red: |
call draw_window ; redraw |
;------------------------------------------------------------------------------ |
align 4 |
still: |
call free_area_if_set_mutex |
|
mcall 23,5 ; wait here for event |
test [close_now],1 ; is close flag set? |
jnz close |
177,21 → 127,21 |
je button |
cmp eax,6 ; mouse event ? |
je mouse |
cmp edi,[menu_data] |
cmp edi,menu_data |
je still ; if main process-ignored |
|
movzx ebx,[edi + parent] ; parent id |
shl ebx,4 |
add ebx,[menu_data] ; ebx = base of parent info |
add ebx,menu_data ; ebx = base of parent info |
call backconvert ; get my id in al |
cmp al,[ebx + child] ; if I'm not child of my parent, I shall die :) |
jne close |
|
jmp still |
;------------------------------------------------------------------------------ |
align 4 |
;--------------------------------------------------------------------- |
key: |
mcall 2 |
; mov eax,2 |
mcall |
mov [last_key],ah |
mov al,[edi + rows] ; number of buttons |
cmp ah,178 ; KEY_UP |
203,8 → 153,7 |
jnz redrawbut |
mov [edi+cur_sel],al |
jmp redrawbut |
;-------------------------------------- |
align 4 |
;--------------------------------------------------------------------- |
.noup: |
cmp ah,177 ; KEY_DOWN |
jne .nodn |
216,8 → 165,7 |
jna redrawbut |
mov [edi + cur_sel],1 |
jmp redrawbut |
;-------------------------------------- |
align 4 |
;--------------------------------------------------------------------- |
.nodn: |
cmp ah,179 ; KEY_LEFT |
je @f |
226,8 → 174,7 |
@@: |
mov ah,[edi + cur_sel] |
jmp button1 |
;-------------------------------------- |
align 4 |
;--------------------------------------------------------------------- |
.noenter: |
cmp ah,176 ; KEY_RIGHT |
je @f |
234,15 → 181,13 |
cmp ah,27 ; ESC |
jne still |
jmp close |
;-------------------------------------- |
align 4 |
@@: |
call get_process_ID |
cmp [main_process_ID],ecx |
jne close |
jmp still |
;------------------------------------------------------------------------------ |
align 4 |
;--------------------------------------------------------------------- |
; include "DEBUG.INC" |
button: ; BUTTON HANDLER |
mcall 17 ; get id |
; dunkaist[ |
250,8 → 195,6 |
setz byte[close_now] ; set (or not set) close_recursive flag |
jz close ; if so,close all menus |
; dunkaist] |
;-------------------------------------- |
align 4 |
button1: |
mov esi,edi |
push edi |
268,8 → 211,6 |
popad |
; look for the next line <ah> times; <ah> = button_id |
push eax |
;-------------------------------------- |
align 4 |
.next_string: |
call searchstartstring |
dec ah |
306,13 → 247,11 |
pop edi |
mov [mousemask],0 |
jmp close |
;-------------------------------------- |
align 4 |
;--------------------------------------------------------------------- |
searchexit: |
pop edi |
jmp still |
;------------------------------------------------------------------------------ |
align 4 |
;--------------------------------------------------------------------- |
runthread: |
inc edi |
|
337,7 → 276,7 |
add cx,141 ; new x_start in cx |
movzx edx,al |
shl edx,4 |
add edx,[menu_data] ; edx points to child's base address |
add edx,menu_data ; edx points to child's base address |
mov [edx + x_start],cx ; xstart for new thread |
mov cx,[esi + y_end] ; y_end in cx |
mov bl,[esi + rows] ; number of buttons in bl |
359,13 → 298,14 |
mov [edx + prev_sel],al ; clear previous selected element |
mov [edx + child],0 |
|
mcall 68,12,0x1000 ; stack of each thread is allocated 4 KB |
add eax,0x1000 ; set the stack pointer to the desired position |
mov edx,eax |
mcall 51,1,thread ; Go ahead! |
cmp [thread_stack],0x1e000 |
jne thread_stack_not_full |
mov [thread_stack],0xE000 |
thread_stack_not_full: |
add [thread_stack],0x2000 ; start new thread |
mcall 51,1,thread,[thread_stack] |
jmp searchexit |
;------------------------------------------------------------------------------ |
align 4 |
;--------------------------------------------------------------------- |
mouse: ; MOUSE EVENT HANDLER |
mcall 37,0 |
mov [screen_mouse_position],eax ; eax = [ Y | X ] relative to screen |
395,24 → 335,18 |
;;;;;; |
mov [edi + cur_sel],al |
mov [edi + prev_sel],bl |
;-------------------------------------- |
align 4 |
redrawbut: |
call draw_only_needed_buttons |
;-------------------------------------- |
align 4 |
noredrawbut: |
call backconvert |
bts [mousemask],eax |
jmp still |
;-------------------------------------- |
align 4 |
;--------------------------------------------------------------------- |
noinwindow: |
call backconvert |
btr [mousemask],eax |
jmp still |
;------------------------------------------------------------------------------ |
align 4 |
;--------------------------------------------------------------------- |
click: |
cmp [mousemask],0 ; not in a window (i.e. menu) |
jne still |
427,90 → 361,34 |
ja close |
cmp ax,MENU_BOTTON_X_POS |
ja still |
;------------------------------------------------------------------------------ |
align 4 |
;--------------------------------------------------------------------- |
close: |
|
movzx ebx,[edi+parent] ; parent id |
shl ebx,4 |
add ebx,[menu_data] ; ebx = base of parent info |
add ebx,menu_data ; ebx = base of parent info |
call backconvert |
cmp [ebx + child],al ; if i am the child of my parent... |
jnz @f |
mov [ebx + child],-1 ; ...my parent now has no children |
;-------------------------------------- |
align 4 |
@@: |
or eax,-1 ; close this thread |
mov [edi + child],al ; my child is not mine |
|
call free_area_if_set_mutex |
call set_mutex_for_free_area |
|
mcall |
;-------------------------------------- |
align 4 |
backconvert: ; convert from pointer to process id |
mov eax,edi |
sub eax,[menu_data] |
sub eax,menu_data |
shr eax,4 |
ret |
;------------------------------------------------------------------------------ |
align 4 |
set_mutex_for_free_area: |
; set mutex for free thread stack area |
push eax ebx |
;-------------------------------------- |
align 4 |
.wait_lock: |
cmp [free_my_area_lock], 0 |
je .get_lock |
mcall 68,1 |
jmp .wait_lock |
;-------------------------------------- |
align 4 |
.get_lock: |
mov eax, 1 |
xchg eax, [free_my_area_lock] |
test eax, eax |
jnz .wait_lock |
mov [free_my_area],ebp |
pop ebx eax |
ret |
;------------------------------------------------------------------------------ |
align 4 |
free_area_if_set_mutex: |
cmp [free_my_area_lock],0 |
je .end |
|
push eax ebx ecx |
mov ecx,[free_my_area] |
|
test ecx,ecx |
jz @f |
mcall 68,13 |
;-------------------------------------- |
align 4 |
@@: |
xor eax,eax |
mov [free_my_area_lock],eax |
pop ecx ebx eax |
;-------------------------------------- |
align 4 |
.end: |
ret |
;------------------------------------------------------------------------------ |
;--------------------------------------------------------------------- |
;================================== |
; get_number |
; load number from [edi] to ebx |
;================================== |
align 4 |
get_number: |
push edi |
xor eax,eax |
xor ebx,ebx |
;-------------------------------------- |
align 4 |
.get_next_char: |
mov al,[edi] |
inc edi |
523,19 → 401,16 |
add ebx,eax |
jmp .get_next_char |
;------------------------------------- |
align 4 |
.finish: |
pop edi |
ret |
;------------------------------------------------------------------------------ |
align 4 |
;--------------------------------------------------------------------- |
get_process_ID: |
mcall 9,procinfo,-1 |
mov edx,eax |
mov ecx,[ebx+30] ; PID |
ret |
;------------------------------------------------------------------------------ |
align 4 |
;--------------------------------------------------------------------- |
program_exist: |
call get_process_ID |
mov [main_process_ID],ecx |
544,7 → 419,6 |
mov ecx,edx |
xor edx,edx |
;----------------------------------------- |
align 4 |
.loop: |
push ecx |
mcall 9,procinfo |
559,24 → 433,19 |
; dph ecx |
mcall 18,2 |
mov edx,1 |
;-------------------------------------- |
align 4 |
@@: |
pop ecx |
loop .loop |
|
;----------------------------------------- |
test edx,edx |
jz @f |
mcall -1 |
;-------------------------------------- |
align 4 |
@@: |
ret |
;------------------------------------------------------------------------------ |
;--------------------------------------------------------------------- |
; ********************************************* |
; ******* WINDOW DEFINITIONS AND DRAW ******** |
; ********************************************* |
align 4 |
draw_window: |
mcall 12,1 ; 1,start of draw |
movzx ebx,[edi + rows] |
597,12 → 466,9 |
call draw_all_buttons |
mcall 12,2 |
ret |
;------------------------------------------------------------------------------ |
align 4 |
;--------------------------------------------------------------------- |
draw_all_buttons: |
xor edx,edx |
;-------------------------------------- |
align 4 |
.new_button: |
call draw_one_button |
inc edx |
609,8 → 475,7 |
cmp dl,[edi + rows] |
jb .new_button |
ret |
;------------------------------------------------------------------------------ |
align 4 |
;--------------------------------------------------------------------- |
draw_only_needed_buttons: |
xor edx,edx |
mov dl,[edi + cur_sel] |
620,8 → 485,7 |
dec dl |
call draw_one_button |
ret |
;------------------------------------------------------------------------------ |
align 4 |
;--------------------------------------------------------------------- |
draw_one_button: |
; receives number of button in dl |
push edx |
636,15 → 500,11 |
cmp esi,0xdfdfdf |
jb nocorrect |
sub esi,0x1b1b1b |
;-------------------------------------- |
align 4 |
nocorrect: |
inc dl |
cmp [edi + cur_sel],dl |
jne .nohighlight |
add esi,0x1a1a1a |
;-------------------------------------- |
align 4 |
.nohighlight: |
or edx,0x20000000 |
; dunkaist[ |
659,15 → 519,12 |
movzx ecx,dl |
inc ecx |
mov edx,[edi + pointer] |
;-------------------------------------- |
align 4 |
.findline: |
cmp byte [edx],13 |
je .linefound |
inc edx |
jmp .findline |
;------------------------------------------------------------------------------ |
align 4 |
;--------------------------------------------------------------------- |
.linefound: |
inc edx |
cmp byte [edx],10 |
678,8 → 535,7 |
mcall 4,,[sc.work_text],,21 |
pop edx |
ret |
;------------------------------------------------------------------------------ |
align 4 |
;--------------------------------------------------------------------- |
searchstartstring: |
mov ecx,40 |
mov al,13 |
688,28 → 544,23 |
cmp byte [edi],10 |
jne searchstartstring |
ret |
;------------------------------------------------------------------------------ |
;--------------------------------------------------------------------- |
;*** DATA AREA **************************************************************** |
menu_mame: |
db '@MENU',0 |
|
align 4 |
free_my_area_lock dd 0 |
free_my_area dd 0 |
thread_stack dd 0xE000 |
processes dd 0 |
|
processes dd 0 |
;-------------------------------------- |
align 4 |
fileinfo: |
.subfunction dd 5 ; 5 - file info; 0 - file read |
.subfunction dd 0 ; 0=READ |
.start dd 0 ; start byte |
.size_high dd 0 ; rezerved |
.size dd 0 ; bytes to read |
.return dd procinfo ; return data pointer |
.size dd 0x10000-mem_end ; blocks to read |
.return dd mem_end ; return data pointer |
.name: |
db '/sys/MENU.DAT',0 ; ASCIIZ dir & filename |
;-------------------------------------- |
align 4 |
|
fileinfo_start: |
.subfunction dd 7 ; 7=START APPLICATION |
.flags dd 0 ; flags |
718,10 → 569,9 |
.rezerved_1 dd 0x0 ; nop |
.name: |
times 50 db ' ' |
;------------------------------------------------------------------------------ |
IM_END: |
;------------------------------------------------------------------------------ |
align 4 |
;--------------------------------------------------------------------- |
I_END: |
;--------------------------------------------------------------------- |
close_now dd ? ; close all processes immediately |
end_pointer dd ? |
buffer dd ? |
729,22 → 579,21 |
|
active_process dd ? |
main_process_ID dd ? |
;-------------------------------------- |
|
screen_mouse_position: |
.y dw ? |
.x dw ? |
;-------------------------------------- |
|
screen_size: |
.y dw ? |
.x dw ? |
;-------------------------------------- |
|
|
sc system_colors |
;-------------------------------------- |
last_key db ? |
;------------------------------------------------------------------------------ |
align 4 |
menu_data dd ? |
;-------------------------------------- |
|
menu_data: |
rb 0x4000 ;x10000 |
|
virtual at 0 ; PROCESSES TABLE (located at menu_data) |
pointer dd ? ; +0 pointer in file |
rows db ? ; +4 numer of strings |
756,14 → 605,12 |
prev_sel db ? ; +12 previous selection |
rb 16-$+1 ; [16 bytes per element] |
end virtual |
;------------------------------------------------------------------------------ |
|
last_key db ? |
;--------------------------------------------------------------------- |
align 4 |
procinfo: |
rb 1024 |
;------------------------------------------------------------------------------ |
align 4 |
rb 0x1000 |
stack_area: |
;------------------------------------------------------------------------------ |
;--------------------------------------------------------------------- |
mem_end: |
;------------------------------------------------------------------------------ |
;--------------------------------------------------------------------- |