diff --git a/data/Tupfile.lua b/data/Tupfile.lua index 75ee62a8be..931ce266ee 100644 --- a/data/Tupfile.lua +++ b/data/Tupfile.lua @@ -383,7 +383,7 @@ tup.append_table(img_files, { {"DEVELOP/MTDBG", PROGS .. "/develop/mtdbg/mtdbg"}, {"DEVELOP/SCANCODE", PROGS .. "/develop/scancode/trunk/scancode"}, {"DEVELOP/T_EDIT", PROGS .. "/other/t_edit/t_edit"}, - {"DEVELOP/test_gets", PROGS .. "/develop/libraries/console/examples/test_gets"}, + {"DEVELOP/test_gets", PROGS .. "/develop/libraries/console_coff/examples/test_gets"}, {"DEVELOP/THREAD", PROGS .. "/develop/examples/thread/trunk/thread"}, {"DEVELOP/INFO/ASM.SYN", PROGS .. "/other/t_edit/info/asm.syn"}, {"DEVELOP/INFO/CPP_KOL_CLA.SYN", PROGS .. "/other/t_edit/info/cpp_kol_cla.syn"}, @@ -415,7 +415,7 @@ tup.append_table(img_files, { {"LIB/ARCHIVER.OBJ", PROGS .. "/fs/kfar/trunk/kfar_arc/kfar_arc.obj"}, {"LIB/BOX_LIB.OBJ", PROGS .. "/develop/libraries/box_lib/trunk/box_lib.obj"}, {"LIB/BUF2D.OBJ", PROGS .. "/develop/libraries/buf2d/trunk/buf2d.obj"}, - {"LIB/CONSOLE.OBJ", PROGS .. "/develop/libraries/console/console.obj"}, + {"LIB/CONSOLE.OBJ", PROGS .. "/develop/libraries/console_coff/console.obj"}, {"LIB/LIBGFX.OBJ", PROGS .. "/develop/libraries/libs-dev/libgfx/libgfx.obj"}, {"LIB/LIBIMG.OBJ", PROGS .. "/develop/libraries/libs-dev/libimg/libimg.obj"}, {"LIB/LIBINI.OBJ", PROGS .. "/develop/libraries/libs-dev/libini/libini.obj"}, @@ -509,9 +509,9 @@ tup.append_table(extra_files, { -- For russian build, add russian-only programs. if build_type == "rus" then tup.append_table(img_files, { {"PERIOD", PROGS .. "/other/period/trunk/period"}, - {"DEVELOP/TESTCON2", PROGS .. "/develop/libraries/console/examples/testcon2_rus"}, + {"DEVELOP/TESTCON2", PROGS .. "/develop/libraries/console_coff/examples/testcon2_rus"}, }) else tup.append_table(img_files, { - {"DEVELOP/TESTCON2", PROGS .. "/develop/libraries/console/examples/testcon2_eng"}, + {"DEVELOP/TESTCON2", PROGS .. "/develop/libraries/console_coff/examples/testcon2_eng"}, }) end if build_type == "rus" then tup.append_table(extra_files, { diff --git a/data/common/pestrip.asm b/data/common/pestrip.asm index 20a79af4d4..96e09e4176 100644 --- a/data/common/pestrip.asm +++ b/data/common/pestrip.asm @@ -27,6 +27,7 @@ end virtual virtual at 0 file filename:pehea,0F8h load NumberOfSections word from 6 +load TimeDateStamp dword from 8 load SizeOfOptionalHeader word from 14h if SizeOfOptionalHeader<>0E0h error Nonstandard PE header @@ -103,14 +104,25 @@ DeltaDeleted = NumBytesDeleted and not (FileAlignment - 1) ; Use store instead of declaring SizeOfHeaders - DeltaDeleted directly in dd ; to avoid the second compilation pass. store dword SizeOfHeaders - DeltaDeleted at SizeOfHeadersField +TimeStampInExportTable = 0 ; sections repeat NumberOfSections file filename:pehea+0F8h+(%-1)*28h,18h -load a dword from $-4 -store dword a-DeltaDeleted at $-4 +load VirtualSize dword from $-10h +load VirtualAddress dword from $-0Ch +load SizeOfRawData dword from $-8 +load PointerToRawData dword from $-4 +PointerToRawData = PointerToRawData - DeltaDeleted +store dword PointerToRawData at $-4 +if DirRVA_EXPORT <> 0 & DirRVA_EXPORT+4 >= VirtualAddress & DirRVA_EXPORT+8 <= VirtualAddress + VirtualSize & DirRVA_EXPORT+8 <= VirtualAddress + SizeOfRawData +TimeStampInExportTable = DirRVA_EXPORT+4 - VirtualAddress + PointerToRawData +end if file filename:pehea+0F8h+(%-1)*28h+24h,4 end repeat ; padding to keep FileAlignment times NumBytesDeleted - DeltaDeleted db 0 ; data file filename:pehea+0F8h+NumberOfSections*28h +if TimeDateStamp <> 0 +store dword TimeDateStamp at TimeStampInExportTable +end if diff --git a/programs/develop/libraries/console/Tupfile.lua b/programs/develop/libraries/console/Tupfile.lua index 41648007d7..f9f9109e60 100644 --- a/programs/develop/libraries/console/Tupfile.lua +++ b/programs/develop/libraries/console/Tupfile.lua @@ -1,2 +1,3 @@ if tup.getconfig("NO_FASM") ~= "" then return end -tup.rule("console.asm", "fasm %f %o " .. tup.getconfig("KPACK_CMD"), "console.obj") +ROOT = "../../../.." +tup.rule("console.asm", "fasm %f %o " .. tup.getconfig("PESTRIP_CMD") .. tup.getconfig("KPACK_CMD"), "console.dll") diff --git a/programs/develop/libraries/console/console.asm b/programs/develop/libraries/console/console.asm index 2798211e3a..574e42bb90 100644 --- a/programs/develop/libraries/console/console.asm +++ b/programs/develop/libraries/console/console.asm @@ -1,31 +1,13 @@ ; ”г­ЄжЁЁ а Ў®вл б Є®­б®«мо ¤«п Їа®Ја ¬¬ Љ®«ЁЎаЁЋ‘ ; diamond, 2006-2008 +format PE console 0.8 DLL at 7FEF0000h -format MS COFF - -public EXPORTS - -section '.flat' code readable align 16 +section '.flat' code readable executable include 'font.inc' include 'conscrl.inc' - -;void __stdcall START(dword state); -START: -; N.B. The current kernel implementation does not require -; evident heap initialization, because if DLL is loaded, heap is already initialized -; (if heap was not initialized, loader does this implicitly). -; So this action does nothing useful, but nothing harmful. - push ebx - push 68 - pop eax - push 11 - pop ebx - int 0x40 - pop ebx - or eax, -1 - ret 4 +include '../../../export.inc' ; €­ЁжЁ «Ё§ жЁп Є®­б®«Ё ; void __stdcall con_init(dword wnd_width, dword wnd_height, @@ -33,6 +15,11 @@ START: align 4 con_init: + mov [con_flags], 7 + mov [con.cursor_height], (15*font_height+50)/100 + mov [con.input_start], con.input_buffer + mov [con.input_end], con.input_buffer + mov [con.entered_char], -1 pop eax pop [con.wnd_width] @@ -1840,6 +1827,7 @@ con.wake: ; Џ®в®Є ®Є­  Є®­б®«Ё. ЋЎа Ў влў Ґв ўў®¤ Ё ўлў®¤. con.thread: + or [con.vscroll_pt], -1 ; Џ®в®Є ॠЈЁагҐв ­  IPC, Є®в®а®Ґ ЁбЇ®«м§гҐвбп в®«мЄ® ¤«п в®Ј®, зв®Ўл ҐЈ® ¬®¦­® Ўл«® "а §Ўг¤Ёвм" push 40 pop eax @@ -1849,6 +1837,7 @@ con.thread: mov al, 60 mov bl, 1 mov ecx, con.ipc_buf + mov byte [ecx+4], 8 push 0x11 pop edx int 0x40 @@ -2545,108 +2534,56 @@ con.def_scr_height dd 300 con.def_wnd_x dd 200 con.def_wnd_y dd 50 -con.init_cmd db 0 con.title_init_console db "Console",0 -struc process_info -{ - cpu_usage dd ? ; +0 - window_stack_position dw ? ; +4 - window_stack_value dw ? ; +6 - dw ? ; +8 - process_name rb 12 ; +10 - memory_start dd ? ; +22 - used_memory dd ? ; +26 - PID dd ? ; +30 - box.x dd ? ; +34 - box.y dd ? ; +38 - box.width dd ? ; +42 - box.height dd ? ; +46 - slot_state dw ? ; +50 - dw ? ; +52 - client_box.x dd ? ; +54 - client_box.y dd ? ; +58 - client_box.width dd ? ; +62 - client_box.height dd ? ; +66 - wnd_state db ? ; +70 - rb (1024-71) -} -process_info_buffer process_info -window_status rd 1 - -con.vscroll_pt dd -1 - -align 16 -EXPORTS: - dd szStart, START - dd szVersion, 0x00020008 - dd szcon_init, con_init - dd szcon_write_asciiz, con_write_asciiz - dd szcon_write_string, con_write_length - dd szcon_printf, con_printf - dd szcon_exit, con_exit - dd szcon_get_flags, con_get_flags - dd szcon_set_flags, con_set_flags - dd szcon_kbhit, con_kbhit - dd szcon_getch, con_getch - dd szcon_getch2, con_getch2 - dd szcon_gets, con_gets - dd szcon_gets2, con_gets2 - dd szcon_get_font_height, con_get_font_height - dd szcon_get_cursor_height,con_get_cursor_height - dd szcon_set_cursor_height,con_set_cursor_height - dd szcon_cls, con_cls - dd szcon_get_cursor_pos, con_get_cursor_pos - dd szcon_set_cursor_pos, con_set_cursor_pos - dd szcon_set_title, con_set_title - dd 0 - -con_flags dd 7 -con.cursor_height dd (15*font_height+50)/100 -con.input_start dd con.input_buffer -con.input_end dd con.input_buffer - -con_esc_attr_n dd 0 -con_esc_attrs dd 0,0,0,0 -con_esc db 0 -con_sci db 0 - -con.entered_char dw -1 -con.bGetchRequested db 0 -con.bWasE0 db 0 - -szStart db 'START',0 - -szcon_init db 'con_init',0 -szcon_write_asciiz db 'con_write_asciiz',0 -szcon_write_string db 'con_write_string',0 -szcon_printf db 'con_printf',0 -szcon_exit db 'con_exit',0 -szVersion db 'version',0 -szcon_get_flags db 'con_get_flags',0 -szcon_set_flags db 'con_set_flags',0 -szcon_kbhit db 'con_kbhit',0 -szcon_getch db 'con_getch',0 -szcon_getch2 db 'con_getch2',0 -szcon_gets db 'con_gets',0 -szcon_gets2 db 'con_gets2',0 -szcon_get_font_height db 'con_get_font_height',0 -szcon_get_cursor_height db 'con_get_cursor_height',0 -szcon_set_cursor_height db 'con_set_cursor_height',0 -szcon_cls db 'con_cls',0 -szcon_get_cursor_pos db 'con_get_cursor_pos',0 -szcon_set_cursor_pos db 'con_set_cursor_pos',0 -szcon_set_title db 'con_set_title',0 +align 4 +data export +export 'console.dll', \ + version, 'version', \ + con_init, 'con_init', \ + con_write_asciiz, 'con_write_asciiz', \ + con_write_length, 'con_write_string', \ + con_printf, 'con_printf', \ + con_exit, 'con_exit', \ + con_get_flags, 'con_get_flags', \ + con_set_flags, 'con_set_flags', \ + con_kbhit, 'con_kbhit', \ + con_getch, 'con_getch', \ + con_getch2, 'con_getch2', \ + con_gets, 'con_gets', \ + con_gets2, 'con_gets2', \ + con_get_font_height, 'con_get_font_height', \ + con_get_cursor_height, 'con_get_cursor_height', \ + con_set_cursor_height, 'con_set_cursor_height', \ + con_cls, 'con_cls', \ + con_get_cursor_pos, 'con_get_cursor_pos', \ + con_set_cursor_pos, 'con_set_cursor_pos', \ + con_set_title, 'con_set_title' +end data +version dd 0x00020008 con.thread_err db 'Cannot create console thread!',13,10,0 con.nomem_err db 'Not enough memory!',13,10,0 con.aFinished db ' [Finished]',0 con.aNull db '(null)',0 con.beep db 0x90, 0x3C, 0x00 -con.ipc_buf dd 0,8,0,0 - db 0 -section '.data' data readable writable align 16 +section '.data' data readable writable +con_flags dd ? +con.cursor_height dd ? +con.input_start dd ? +con.input_end dd ? + +con_esc_attr_n dd ? +con_esc_attrs dd ?,?,?,? +con_esc db ? +con_sci db ? + +con.entered_char dw ? +con.bGetchRequested db ? +con.bWasE0 db ? + +con.init_cmd db ? con.finished_title rb 256 @@ -2675,12 +2612,15 @@ con.bUpPressed_saved rb 1 con.bDownPressed_saved rb 1 con.bScrollingUp_saved rb 1 con.bScrollingDown_saved rb 1 +con.vscroll_pt dd ? con.input_buffer rw 128 con.input_buffer_end = $ con.kbd_layout rb 128 +con.ipc_buf rb 0x11 + ; 1 = exit, 2 = set title, 3 = redraw, 4 = getch con.thread_op rb 1 con.bUpPressed rb 1 @@ -2690,3 +2630,29 @@ con.bScrollingDown rb 1 con.stack rb 1024 con.stack_top = $ + +struc process_info +{ + cpu_usage dd ? ; +0 + window_stack_position dw ? ; +4 + window_stack_value dw ? ; +6 + dw ? ; +8 + process_name rb 12 ; +10 + memory_start dd ? ; +22 + used_memory dd ? ; +26 + PID dd ? ; +30 + box.x dd ? ; +34 + box.y dd ? ; +38 + box.width dd ? ; +42 + box.height dd ? ; +46 + slot_state dw ? ; +50 + dw ? ; +52 + client_box.x dd ? ; +54 + client_box.y dd ? ; +58 + client_box.width dd ? ; +62 + client_box.height dd ? ; +66 + wnd_state db ? ; +70 + rb (1024-71) +} +process_info_buffer process_info +window_status rd 1 diff --git a/programs/develop/libraries/console/console_en.txt b/programs/develop/libraries/console/console_en.txt index c91986a8c6..a994e4b8ad 100644 --- a/programs/develop/libraries/console/console_en.txt +++ b/programs/develop/libraries/console/console_en.txt @@ -1,4 +1,4 @@ -console.obj exports the following functions +console.dll exports the following functions typedef unsigned long dword; /* 32-bit unsigned integer */ typedef unsigned short word; /* 16-bit unsigned integer */ diff --git a/programs/develop/libraries/console/console_ru.txt b/programs/develop/libraries/console/console_ru.txt index 26ce0895fa..c715a1976e 100644 --- a/programs/develop/libraries/console/console_ru.txt +++ b/programs/develop/libraries/console/console_ru.txt @@ -1,4 +1,4 @@ -console.obj экспортирует следующие функции: +console.dll экспортирует следующие функции: typedef unsigned long dword; /* 32-битное беззнаковое целое */ typedef unsigned short word; /* 16-битное беззнаковое целое */ diff --git a/programs/develop/libraries/console/examples/Tupfile.lua b/programs/develop/libraries/console/examples/Tupfile.lua index b34ba0b9da..eba5765228 100644 --- a/programs/develop/libraries/console/examples/Tupfile.lua +++ b/programs/develop/libraries/console/examples/Tupfile.lua @@ -1,2 +1,3 @@ if tup.getconfig("NO_FASM") ~= "" then return end -tup.foreach_rule("*.asm", "fasm %f %o " .. tup.getconfig("KPACK_CMD"), "%B") +ROOT = "../../../../.." +tup.foreach_rule("*.asm", "fasm %f %o " .. tup.getconfig("PESTRIP_CMD") .. tup.getconfig("KPACK_CMD"), "%B") diff --git a/programs/develop/libraries/console/examples/test_getch.asm b/programs/develop/libraries/console/examples/test_getch.asm index 100398b2ca..dcb582f1b4 100644 --- a/programs/develop/libraries/console/examples/test_getch.asm +++ b/programs/develop/libraries/console/examples/test_getch.asm @@ -1,41 +1,9 @@ - +format PE console 0.8 include 'proc32.inc' - -DLL_ENTRY equ 1 -DLL_EXIT equ -1 -REQ_DLL_VER equ 3 - -use32 - db 'MENUET01' - dd 1 - dd start - dd i_end - dd mem - dd mem - dd 0 - dd 0 +include '../../../../import.inc' start: - stdcall load_dll_and_import, dllname, imports - test eax, eax - jz exit - -; check version - cmp word [dll_ver], REQ_DLL_VER - jb exit - cmp word [dll_ver+2], REQ_DLL_VER - ja exit - push DLL_ENTRY - call [dll_start] - -; yes! Now do some work (getch() demo in this case). - - push caption - push -1 - push -1 - push -1 - push -1 - call [con_init] + invoke con_set_title, caption ; C-equivalent of the following code: ; con_printf(start_string); @@ -78,91 +46,20 @@ done: push 1 call [con_exit] exit: - or eax, -1 - int 0x40 - -proc load_dll_and_import stdcall, _dllname:dword, _imports:dword - pushad -; load DLL - push 68 - pop eax - push 19 - pop ebx - mov ecx, [_dllname] - int 0x40 - test eax, eax - jz import_fail - -; initialize import - mov edi, eax - mov esi, [_imports] -import_loop: - lodsd - test eax, eax - jz import_done - mov edx, edi -import_find: - mov ebx, [edx] - test ebx, ebx - jz import_not_found - push eax -@@: - mov cl, [eax] - cmp cl, [ebx] - jnz import_find_next - test cl, cl - jz import_found - inc eax - inc ebx - jmp @b -import_find_next: - pop eax - add edx, 8 - jmp import_find -import_found: - pop eax - mov eax, [edx+4] - mov [esi-4], eax - jmp import_loop -import_not_found: -import_fail: - popad - xor eax, eax - ret -import_done: - popad - xor eax, eax - inc eax - ret -endp + xor eax, eax + ret align 4 - -imports: -dll_start dd szStart -dll_ver dd szVersion -con_init dd szcon_init -con_printf dd szcon_printf -con_exit dd szcon_exit -con_getch dd szcon_getch - dd 0 - -szStart db 'START',0 -szVersion db 'version',0 -szcon_init db 'con_init',0 -szcon_printf db 'con_printf',0 -szcon_exit db 'con_exit',0 -szcon_getch db 'con_getch',0 - -dllname db '/sys/lib/console.obj',0 +data import +library console, 'console.dll' +import console, \ + con_set_title, 'con_set_title', \ + con_printf, 'con_printf', \ + con_exit, 'con_exit', \ + con_getch, 'con_getch' +end data caption db 'Console test - getch()',0 start_string db 'Press any key to see its code, or Esc to exit',10,0 string_normal db 'normal character with code %d=0x%02X',10,0 string_extended db 'extended character with code %d=0x%02X',10,0 - -i_end: - -align 4 -rb 2048 ; stack -mem: diff --git a/programs/develop/libraries/console/examples/test_gets.asm b/programs/develop/libraries/console/examples/test_gets.asm index 9d3eb1fff6..13eb7f01e9 100644 --- a/programs/develop/libraries/console/examples/test_gets.asm +++ b/programs/develop/libraries/console/examples/test_gets.asm @@ -1,41 +1,9 @@ - +format PE console 0.8 include 'proc32.inc' - -DLL_ENTRY equ 1 -DLL_EXIT equ -1 -REQ_DLL_VER equ 3 - -use32 - db 'MENUET01' - dd 1 - dd start - dd i_end - dd mem - dd mem - dd 0 - dd 0 +include '../../../../import.inc' start: - stdcall load_dll_and_import, dllname, imports - test eax, eax - jz exit - -; check version - cmp word [dll_ver], REQ_DLL_VER - jb exit - cmp word [dll_ver+2], REQ_DLL_VER - ja exit - push DLL_ENTRY - call [dll_start] - -; yes! Now do some work (gets() demo in this case). - - push caption - push -1 - push -1 - push -1 - push -1 - call [con_init] + invoke con_set_title, caption ; C-equivalent of the following code: ; for (;;) @@ -65,92 +33,22 @@ done: push 1 call [con_exit] exit: - or eax, -1 - int 0x40 - -proc load_dll_and_import stdcall, _dllname:dword, _imports:dword - pushad -; load DLL - push 68 - pop eax - push 19 - pop ebx - mov ecx, [_dllname] - int 0x40 - test eax, eax - jz import_fail - -; initialize import - mov edi, eax - mov esi, [_imports] -import_loop: - lodsd - test eax, eax - jz import_done - mov edx, edi -import_find: - mov ebx, [edx] - test ebx, ebx - jz import_not_found - push eax -@@: - mov cl, [eax] - cmp cl, [ebx] - jnz import_find_next - test cl, cl - jz import_found - inc eax - inc ebx - jmp @b -import_find_next: - pop eax - add edx, 8 - jmp import_find -import_found: - pop eax - mov eax, [edx+4] - mov [esi-4], eax - jmp import_loop -import_not_found: -import_fail: - popad xor eax, eax ret -import_done: - popad - xor eax, eax - inc eax - ret -endp + align 4 - -imports: -dll_start dd szStart -dll_ver dd szVersion -con_init dd szcon_init -con_write_asciiz dd szcon_write_asciiz -con_exit dd szcon_exit -con_gets dd szcon_gets - dd 0 - -szStart db 'START',0 -szVersion db 'version',0 -szcon_init db 'con_init',0 -szcon_write_asciiz db 'con_write_asciiz',0 -szcon_exit db 'con_exit',0 -szcon_gets db 'con_gets',0 - -dllname db '/sys/lib/console.obj',0 +data import +library console, 'console.dll' +import console, \ + con_set_title, 'con_set_title', \ + con_write_asciiz, 'con_write_asciiz', \ + con_exit, 'con_exit', \ + con_gets, 'con_gets' +end data caption db 'Console test - gets()',0 str1 db 'Enter string (empty for exit): ',0 str2 db 'You entered: ',0 -i_end: - s rb 256 - -align 4 -rb 2048 ; stack -mem: diff --git a/programs/develop/libraries/console/examples/test_gets2.asm b/programs/develop/libraries/console/examples/test_gets2.asm index 827743d03c..f5cec9c0b1 100644 --- a/programs/develop/libraries/console/examples/test_gets2.asm +++ b/programs/develop/libraries/console/examples/test_gets2.asm @@ -1,35 +1,8 @@ - +format PE GUI 0.8 ; initialize console ourselves include 'proc32.inc' - -DLL_ENTRY equ 1 -DLL_EXIT equ -1 -REQ_DLL_VER equ 4 - -use32 - db 'MENUET01' - dd 1 - dd start - dd i_end - dd mem - dd mem - dd 0 - dd 0 +include '../../../../import.inc' start: - stdcall load_dll_and_import, dllname, imports - test eax, eax - jz exit - -; check version - cmp word [dll_ver], REQ_DLL_VER - jb exit - cmp word [dll_ver+2], REQ_DLL_VER - ja exit - push DLL_ENTRY - call [dll_start] - -; yes! Now do some work (gets2() demo in this case). - push caption push 25 push 80 @@ -66,8 +39,8 @@ done: push 1 call [con_exit] exit: - or eax, -1 - int 0x40 + xor eax, eax + ret proc mycallback stdcall, keycode:dword, pstr:dword, pn:dword, ppos:dword mov eax, [keycode] @@ -160,80 +133,16 @@ proc mycallback stdcall, keycode:dword, pstr:dword, pn:dword, ppos:dword ret endp -proc load_dll_and_import stdcall, _dllname:dword, _imports:dword - pushad -; load DLL - push 68 - pop eax - push 19 - pop ebx - mov ecx, [_dllname] - int 0x40 - test eax, eax - jz import_fail - -; initialize import - mov edi, eax - mov esi, [_imports] -import_loop: - lodsd - test eax, eax - jz import_done - mov edx, edi -import_find: - mov ebx, [edx] - test ebx, ebx - jz import_not_found - push eax -@@: - mov cl, [eax] - cmp cl, [ebx] - jnz import_find_next - test cl, cl - jz import_found - inc eax - inc ebx - jmp @b -import_find_next: - pop eax - add edx, 8 - jmp import_find -import_found: - pop eax - mov eax, [edx+4] - mov [esi-4], eax - jmp import_loop -import_not_found: -import_fail: - popad - xor eax, eax - ret -import_done: - popad - xor eax, eax - inc eax - ret -endp align 4 - -imports: -dll_start dd szStart -dll_ver dd szVersion -con_init dd szcon_init -con_write_asciiz dd szcon_write_asciiz -con_exit dd szcon_exit -con_gets2 dd szcon_gets2 - dd 0 - -szStart db 'START',0 -szVersion db 'version',0 -szcon_init db 'con_init',0 -szcon_write_asciiz db 'con_write_asciiz',0 -szcon_exit db 'con_exit',0 -szcon_gets2 db 'con_gets2',0 - -dllname db '/sys/lib/console.obj',0 +data import +library console, 'console.dll' +import console, \ + con_init, 'con_init', \ + con_write_asciiz, 'con_write_asciiz', \ + con_exit, 'con_exit', \ + con_gets2, 'con_gets2' +end data caption db 'Console test - gets2()',0 str1 db 'Enter string (empty for exit): ',0 @@ -246,10 +155,4 @@ str5.len = $ - str5 str6 db 'next line in the history' str6.len = $ - str6 -i_end: - s rb 256 - -align 4 -rb 2048 ; stack -mem: diff --git a/programs/develop/libraries/console/examples/testcon.asm b/programs/develop/libraries/console/examples/testcon.asm index e868fadcee..1161485460 100644 --- a/programs/develop/libraries/console/examples/testcon.asm +++ b/programs/develop/libraries/console/examples/testcon.asm @@ -1,58 +1,20 @@ -use32 - db 'MENUET01' - dd 1 - dd start - dd i_end - dd mem - dd mem - dd 0 - dd 0 - -; useful includes -include '../../../../macros.inc' -purge mov,add,sub -include '../../../../proc32.inc' -include '../../../../dll.inc' +format PE console 0.8 +include '../../../../import.inc' start: -; First 3 steps are intended to load/init console DLL -; and are identical for all console programs - -; load DLL - stdcall dll.Load, @IMPORT - test eax, eax - jnz exit - -; yes! Now do some work (say helloworld in this case). - push caption - push -1 - push -1 - push -1 - push -1 - call [con_init] push aHelloWorld call [con_write_asciiz] push 0 call [con_exit] -exit: - or eax, -1 - int 0x40 + xor eax, eax + ret -caption db 'Console test',0 aHelloWorld db 'Hello, World!',10,0 align 4 -@IMPORT: -library console, 'console.obj' +data import +library console, 'console.dll' import console, \ - con_start, 'START', \ - con_init, 'con_init', \ con_write_asciiz, 'con_write_asciiz', \ - con_exit, 'con_exit', \ - con_gets, 'con_gets' -i_end: - - -align 4 -rb 2048 ; stack -mem: + con_exit, 'con_exit' +end data diff --git a/programs/develop/libraries/console/examples/testcon2_eng.asm b/programs/develop/libraries/console/examples/testcon2_eng.asm index 51410247e9..cb5f04c61a 100644 --- a/programs/develop/libraries/console/examples/testcon2_eng.asm +++ b/programs/develop/libraries/console/examples/testcon2_eng.asm @@ -1,41 +1,9 @@ - +format PE console 0.8 include 'proc32.inc' - -DLL_ENTRY equ 1 -DLL_EXIT equ -1 -REQ_DLL_VER equ 2 - -use32 - db 'MENUET01' - dd 1 - dd start - dd i_end - dd mem - dd mem - dd 0 - dd 0 +include '../../../../import.inc' start: - stdcall load_dll_and_import, dllname, imports - test eax, eax - jz exit - -; check version - cmp word [dll_ver], REQ_DLL_VER - jb exit - cmp word [dll_ver+2], REQ_DLL_VER - ja exit - push DLL_ENTRY - call [dll_start] - -; yes! Now do some work (show color strings in this case). - - push caption - push -1 - push -1 - push -1 - push -1 - call [con_init] + invoke con_set_title, caption ; C-equivalent of the following code: ; for (ebx=0;ebx<0x100;ebx++) ; { @@ -67,85 +35,19 @@ start: push 0 call [con_exit] exit: - or eax, -1 - int 0x40 - -proc load_dll_and_import stdcall, _dllname:dword, _imports:dword - pushad -; load DLL - push 68 - pop eax - push 19 - pop ebx - mov ecx, [_dllname] - int 0x40 - test eax, eax - jz import_fail - -; initialize import - mov edi, eax - mov esi, [_imports] -import_loop: - lodsd - test eax, eax - jz import_done - mov edx, edi -import_find: - mov ebx, [edx] - test ebx, ebx - jz import_not_found - push eax -@@: - mov cl, [eax] - cmp cl, [ebx] - jnz import_find_next - test cl, cl - jz import_found - inc eax - inc ebx - jmp @b -import_find_next: - pop eax - add edx, 8 - jmp import_find -import_found: - pop eax - mov eax, [edx+4] - mov [esi-4], eax - jmp import_loop -import_not_found: -import_fail: - popad xor eax, eax ret -import_done: - popad - xor eax, eax - inc eax - ret -endp align 4 - -imports: -dll_start dd szStart -dll_ver dd szVersion -con_init dd szcon_init -con_write_asciiz dd szcon_write_asciiz -con_printf dd szcon_printf -con_set_flags dd szcon_set_flags -con_exit dd szcon_exit - dd 0 - -szStart db 'START',0 -szVersion db 'version',0 -szcon_init db 'con_init',0 -szcon_write_asciiz db 'con_write_asciiz',0 -szcon_printf db 'con_printf',0 -szcon_set_flags db 'con_set_flags',0 -szcon_exit db 'con_exit',0 - -dllname db '/sys/lib/console.obj',0 +data import +library console, 'console.dll' +import console, \ + con_set_title, 'con_set_title', \ + con_write_asciiz, 'con_write_asciiz', \ + con_printf, 'con_printf', \ + con_set_flags, 'con_set_flags', \ + con_exit, 'con_exit' +end data caption db 'Console test - colors',0 t1 db 'Color 0x%02X: ',0 @@ -153,9 +55,3 @@ text db 'This is sample text.',10,0 text2 db 27,'[7mAnd this is an example of ' db 27,'[1;36;41mEsc' db 27,'[7m-sequences.',10,0 - -i_end: - -align 4 -rb 2048 ; stack -mem: diff --git a/programs/develop/libraries/console/examples/testcon2_rus.asm b/programs/develop/libraries/console/examples/testcon2_rus.asm index eb7f32a6b9..746b1d6b1f 100644 --- a/programs/develop/libraries/console/examples/testcon2_rus.asm +++ b/programs/develop/libraries/console/examples/testcon2_rus.asm @@ -1,41 +1,9 @@ - +format PE console 0.8 include 'proc32.inc' - -DLL_ENTRY equ 1 -DLL_EXIT equ -1 -REQ_DLL_VER equ 2 - -use32 - db 'MENUET01' - dd 1 - dd start - dd i_end - dd mem - dd mem - dd 0 - dd 0 +include '../../../../import.inc' start: - stdcall load_dll_and_import, dllname, imports - test eax, eax - jz exit - -; check version - cmp word [dll_ver], REQ_DLL_VER - jb exit - cmp word [dll_ver+2], REQ_DLL_VER - ja exit - push DLL_ENTRY - call [dll_start] - -; yes! Now do some work (show color strings in this case). - - push caption - push -1 - push -1 - push -1 - push -1 - call [con_init] + invoke con_set_title, caption ; C-equivalent of the following code: ; for (ebx=0;ebx<0x100;ebx++) ; { @@ -67,85 +35,19 @@ start: push 0 call [con_exit] exit: - or eax, -1 - int 0x40 - -proc load_dll_and_import stdcall, _dllname:dword, _imports:dword - pushad -; load DLL - push 68 - pop eax - push 19 - pop ebx - mov ecx, [_dllname] - int 0x40 - test eax, eax - jz import_fail - -; initialize import - mov edi, eax - mov esi, [_imports] -import_loop: - lodsd - test eax, eax - jz import_done - mov edx, edi -import_find: - mov ebx, [edx] - test ebx, ebx - jz import_not_found - push eax -@@: - mov cl, [eax] - cmp cl, [ebx] - jnz import_find_next - test cl, cl - jz import_found - inc eax - inc ebx - jmp @b -import_find_next: - pop eax - add edx, 8 - jmp import_find -import_found: - pop eax - mov eax, [edx+4] - mov [esi-4], eax - jmp import_loop -import_not_found: -import_fail: - popad xor eax, eax ret -import_done: - popad - xor eax, eax - inc eax - ret -endp align 4 - -imports: -dll_start dd szStart -dll_ver dd szVersion -con_init dd szcon_init -con_write_asciiz dd szcon_write_asciiz -con_printf dd szcon_printf -con_set_flags dd szcon_set_flags -con_exit dd szcon_exit - dd 0 - -szStart db 'START',0 -szVersion db 'version',0 -szcon_init db 'con_init',0 -szcon_write_asciiz db 'con_write_asciiz',0 -szcon_printf db 'con_printf',0 -szcon_set_flags db 'con_set_flags',0 -szcon_exit db 'con_exit',0 - -dllname db '/sys/lib/console.obj',0 +data import +library console, 'console.dll' +import console, \ + con_set_title, 'con_set_title', \ + con_write_asciiz, 'con_write_asciiz', \ + con_printf, 'con_printf', \ + con_set_flags, 'con_set_flags', \ + con_exit, 'con_exit' +end data caption db 'Console test - colors',0 t1 db '–ўҐв 0x%02X: ',0 @@ -153,9 +55,3 @@ text db ' text2 db 27,'[7mЂ нв® ЇаЁ¬Ґа ЁбЇ®«м§®ў ­Ёп ' db 27,'[1;36;41mEsc' db 27,'[7m-Ї®б«Ґ¤®ў вҐ«м­®б⥩.',10,0 - -i_end: - -align 4 -rb 2048 ; stack -mem: diff --git a/programs/develop/libraries/console_coff/Tupfile.lua b/programs/develop/libraries/console_coff/Tupfile.lua new file mode 100644 index 0000000000..41648007d7 --- /dev/null +++ b/programs/develop/libraries/console_coff/Tupfile.lua @@ -0,0 +1,2 @@ +if tup.getconfig("NO_FASM") ~= "" then return end +tup.rule("console.asm", "fasm %f %o " .. tup.getconfig("KPACK_CMD"), "console.obj") diff --git a/programs/develop/libraries/console_coff/build.bat b/programs/develop/libraries/console_coff/build.bat new file mode 100644 index 0000000000..b968338fb1 --- /dev/null +++ b/programs/develop/libraries/console_coff/build.bat @@ -0,0 +1,3 @@ +fasm console.asm console.obj +kpack console.obj +pause \ No newline at end of file diff --git a/programs/develop/libraries/console_coff/conscrl.inc b/programs/develop/libraries/console_coff/conscrl.inc new file mode 100644 index 0000000000..24944515cb --- /dev/null +++ b/programs/develop/libraries/console_coff/conscrl.inc @@ -0,0 +1,45 @@ +; ‚бЇ®¬®Ј вҐ«м­л© д ©« ¤«п console.inc - ®ЇЁб ­ЁҐ scrollbar +; ‚ҐавЁЄ «м­ п Їа®ЄагвЄ  +virtual at 0 +file 'conscrlv.bmp', 36h +; sanity check +load a1 word from 0 +load a2 dword from 0xE +if (a1 <> 'BM') | (a2 <> 0x28) +error 'conscrlv.bmp: not BMP file!' +end if +load con.vscroll_width dword from 0x12 +load con.vscroll_height dword from 0x16 +load a1 dword from 0x1A +if a1 <> 0x180001 +error 'conscrlv.bmp: must be 24-bit bitmap!' +end if +end virtual + +con.vscroll_btn_height = 21 +con.vscroll_bgr_height = 2 +con.vscroll_bar_height1 = 2 +con.vscroll_bar_height2 = 1 +con.vscroll_bar_height3 = 2 + +if con.vscroll_btn_height*4 + con.vscroll_bgr_height*2 \ + + con.vscroll_bar_height1 + con.vscroll_bar_height2 + con.vscroll_bar_height3 \ + <> con.vscroll_height +error 'conscrlv.bmp: invalid dimensions!' +end if + +; ‡ Јаг¦ Ґ¬ ¤ ­­лҐ BMP, ­  室㠯८Ўа §гп Ёе ў ¤ ­­лҐ ¤«п 7-© дг­ЄжЁЁ +con.vscroll: +repeat con.vscroll_height + file 'conscrlv.bmp':36h + ((con.vscroll_width*3+3) and not 3)*(con.vscroll_height - %),\ + con.vscroll_width*3 +end repeat +con.vscroll_btn1 = con.vscroll +con.vscroll_btn2 = con.vscroll + con.vscroll_btn_height*con.vscroll_width*3 +con.vscroll_btn3 = con.vscroll + 2*con.vscroll_btn_height*con.vscroll_width*3 +con.vscroll_btn4 = con.vscroll + 3*con.vscroll_btn_height*con.vscroll_width*3 +con.vscroll_bgr1 = con.vscroll + 4*con.vscroll_btn_height*con.vscroll_width*3 +con.vscroll_bgr2 = con.vscroll_bgr1 + con.vscroll_bgr_height*con.vscroll_width*3 +con.vscroll_bar1 = con.vscroll_bgr2 + con.vscroll_bgr_height*con.vscroll_width*3 +con.vscroll_bar2 = con.vscroll_bar1 + con.vscroll_bar_height1*con.vscroll_width*3 +con.vscroll_bar3 = con.vscroll_bar2 + con.vscroll_bar_height2*con.vscroll_width*3 diff --git a/programs/develop/libraries/console_coff/conscrlv.bmp b/programs/develop/libraries/console_coff/conscrlv.bmp new file mode 100644 index 0000000000..1ccc67f00c Binary files /dev/null and b/programs/develop/libraries/console_coff/conscrlv.bmp differ diff --git a/programs/develop/libraries/console_coff/console.asm b/programs/develop/libraries/console_coff/console.asm new file mode 100644 index 0000000000..2798211e3a --- /dev/null +++ b/programs/develop/libraries/console_coff/console.asm @@ -0,0 +1,2692 @@ +; ”г­ЄжЁЁ а Ў®вл б Є®­б®«мо ¤«п Їа®Ја ¬¬ Љ®«ЁЎаЁЋ‘ +; diamond, 2006-2008 + + +format MS COFF + +public EXPORTS + +section '.flat' code readable align 16 + +include 'font.inc' +include 'conscrl.inc' + +;void __stdcall START(dword state); +START: +; N.B. The current kernel implementation does not require +; evident heap initialization, because if DLL is loaded, heap is already initialized +; (if heap was not initialized, loader does this implicitly). +; So this action does nothing useful, but nothing harmful. + push ebx + push 68 + pop eax + push 11 + pop ebx + int 0x40 + pop ebx + or eax, -1 + ret 4 + +; €­ЁжЁ «Ё§ жЁп Є®­б®«Ё +; void __stdcall con_init(dword wnd_width, dword wnd_height, +; dword scr_width, dword scr_height, const char* title); + +align 4 +con_init: + + pop eax + pop [con.wnd_width] + pop [con.wnd_height] + pop [con.scr_width] + pop [con.scr_height] + pop [con.title] + push eax + + push ebx + + mov [con.init_cmd],1 + + mov ecx, 4 + mov eax, con.wnd_width + mov edx, con.def_wnd_width +.1: + cmp dword [eax], -1 + jnz @f + mov ebx, [edx] + mov [eax], ebx +@@: + add eax, 4 + add edx, 4 + loop .1 +; allocate memory for console data & bitmap data + mov eax, [con.scr_width] + mul [con.scr_height] + lea ecx, [eax+eax] + mov eax, [con.wnd_width] + mul [con.wnd_height] + imul eax, font_width*font_height + mov ebx, eax + push ebx ecx + add ecx, eax + push 68 + pop eax + push 12 + pop ebx + int 0x40 + pop ecx ebx + mov edx, con.nomem_err + test eax, eax + jz con.fatal + mov [con.data], eax + push edi + mov edi, eax + shr ecx, 1 + mov ax, 0x0720 + rep stosw + mov ecx, ebx + mov [con.image], edi + xor eax, eax + rep stosb + pop edi + and byte [con_flags+1], not 2 +; create console thread + push 51 + pop eax + xor ebx, ebx + inc ebx + mov ecx, con.thread + mov edx, con.stack_top + int 0x40 + mov edx, con.thread_err + test eax, eax + js con.fatal + mov [con.console_tid], eax + pop ebx + ret +con.fatal: +; output string to debug board and die + mov cl, [edx] + test cl, cl + jz @f + push 63 + pop eax + xor ebx, ebx + inc ebx + int 0x40 + inc edx + jmp con.fatal +@@: + or eax, -1 + int 0x40 + +; dword __stdcall con_get_flags(void); +con_get_flags: + mov eax, [con_flags] + ret + +; dword __stdcall con_set_flags(dword flags); +con_set_flags: + mov eax, [esp+4] + and ah, not 2 + xchg eax, [con_flags] + ret 4 + +; dword __stdcall con_get_font_height(void); +con_get_font_height: + mov eax, font_height + ret + +; int __stdcall con_get_cursor_height(void); +con_get_cursor_height: + mov eax, [con.cursor_height] + ret + +; int __stdcall con_set_cursor_height(int new_height); +con_set_cursor_height: + mov eax, [esp+4] + cmp eax, font_height + jae @f + xchg eax, [con.cursor_height] + ret 4 +@@: + mov eax, [con.cursor_height] + ret 4 + +con_init_check: + mov ah,[con.init_cmd] + test ah,ah + jne cmd_init_yes + + push con.title_init_console + push -1 + push -1 + push -1 + push -1 + + call con_init + + cmd_init_yes: + + ret +; void __stdcall con_write_asciiz(const char* string); +con_write_asciiz: + call con_init_check + push ebx esi + or ebx, -1 + mov esi, [esp+12] + call con.write + pop esi ebx + ret 4 + +; void __stdcall con_write_string(const char* string, dword length); +con_write_length: + push ebx esi + mov esi, [esp+12] + mov ebx, [esp+16] + call con.write + pop esi ebx + ret 8 + +; Љ ¦¤л© бЁ¬ў®« Є« ббЁдЁжЁагҐвбп Є Є ®¤Ё­ Ё§ +con.printfc.normal = 0 ; ­®а¬ «м­л© бЁ¬ў®« +con.printfc.percent = 1 ; '%' +con.printfc.dot = 2 ; '.' +con.printfc.asterisk = 3 ; '*' +con.printfc.zero = 4 ; '0' +con.printfc.digit = 5 ; ­Ґ­г«Ґў п жЁда  +con.printfc.plus = 6 ; '+' +con.printfc.minus = 7 ; '-' +con.printfc.sharp = 8 ; '#' +con.printfc.space = 9 ; ' ' +con.printfc.long = 10 ; 'l' for 'long' +con.printfc.short = 11 ; 'h' for 'short' +con.printfc.dec = 12 ; 'd' = print decimal +con.printfc.oct = 13 ; 'o' = print octal +con.printfc.unsigned = 14 ; 'u' = print unsigned decimal +con.printfc.hex = 15 ; 'x' = print hexadecimal +con.printfc.pointer = 16 ; 'p' = print pointer +con.printfc.char = 17 ; 'c' = print char +con.printfc.string = 18 ; 's' = print string + +macro set char,type +{store byte con.printfc.#type at con.charcodes + char - ' '} + +con.charcodes: +times 'x'-' '+1 db con.printfc.normal + set '%', percent + set '.', dot + set '*', asterisk + set '0', zero + set '1', digit + set '2', digit + set '3', digit + set '4', digit + set '5', digit + set '6', digit + set '7', digit + set '8', digit + set '9', digit + set ' ', space + set '#', sharp + set '+', plus + set '-', minus + set 'X', hex + set 'x', hex + set 'c', char + set 'd', dec + set 'h', short + set 'i', dec + set 'l', long + set 'o', oct + set 'p', pointer + set 's', string + set 'u', unsigned +purge set +align 4 +con.charjump: + dd con_printf.normal + dd con_printf.percent + dd con_printf.dot + dd con_printf.asterisk + dd con_printf.zero + dd con_printf.digit + dd con_printf.plus + dd con_printf.minus + dd con_printf.sharp + dd con_printf.space + dd con_printf.long + dd con_printf.short + dd con_printf.dec + dd con_printf.oct + dd con_printf.unsigned + dd con_printf.hex + dd con_printf.pointer + dd con_printf.char + dd con_printf.string + +; int __cdecl con_printf(const char* format, ...) +con_printf: + call con_init_check + xor eax, eax + pushad + call con.get_data_ptr + lea ebp, [esp+20h+8] + mov esi, [ebp-4] + sub esp, 64 ; reserve space for buffer +.loop: + xor eax, eax + lodsb + test al, al + jz .done + cmp al, '%' + jz .spec_begin +.normal: + call con.write_char_ex + inc dword [esp+64+28] + jmp .loop +.errspec: +.percent: + add esp, 12 + jmp .normal +.spec_begin: + xor ebx, ebx +; bl = вЁЇ Ї®§ЁжЁЁ: +; 0 = ­ з «® +; 1 = Їа®зЁв ­ ўҐ¤гйЁ© 0 ў бЇҐжЁдЁЄ жЁЁ д®а¬ в  +; 2 = зЁв Ґ¬ Ї®«Ґ иЁаЁ­л +; 3 = зЁв Ґ¬ Ї®«Ґ в®з­®бвЁ +; 4 = Їа®зЁв ­® Ї®«Ґ а §¬Ґа   аЈг¬Ґ­в  +; 5 = зЁв Ґ¬ Ї®«Ґ вЁЇ  +; bh = д« ЈЁ: +; 1 = д« Ј '#', ўлў®¤Ёвм 0/0x/0X +; 2 = д« Ј '-', ўла ў­Ёў ­ЁҐ ў«Ґў® +; 4 = д« Ј '0', ¤®Ї®«­Ґ­ЁҐ ­г«п¬Ё +; 8 = д« Ј 'h', Є®а®вЄЁ©  аЈг¬Ґ­в + push -1 +; dword [esp+8] = precision + push -1 +; dword [esp+4] = width + push 0 +; byte [esp] = д« Ј 0/'+'/' ' +.spec: + xor eax, eax + lodsb + test al, al + jz .done + cmp al, ' ' + jb .normal + cmp al, 'x' + ja .normal + movzx ecx, byte [con.charcodes + eax - ' '] + jmp dword[con.charjump + ecx*4] + +.sharp: + test bl, bl + jnz .errspec + or bh, 1 + jmp .spec +.minus: + test bl, bl + jnz .errspec + or bh, 2 + jmp .spec +.plus: +.space: + test bl, bl + jnz .errspec + cmp byte [esp], '+' + jz .spec + mov byte [esp], al + jmp .spec +.zero: + test bl, bl + jnz .digit + test bh, 2 + jnz .spec + or bh, 4 + inc ebx + jmp .spec +.digit: + sub al, '0' + cmp bl, 2 + ja .precision + mov bl, 2 + xchg eax, [esp+4] + test eax, eax + js .spec + lea eax, [eax*5] + add eax, eax + add [esp+4], eax + jmp .spec +.precision: + cmp bl, 3 + jnz .errspec + xchg eax, [esp+8] + lea eax, [eax*5] + add eax, eax + add [esp+8], eax + jmp .spec +.asterisk: + mov eax, [ebp] + add ebp, 4 + cmp bl, 2 + ja .asterisk_precision + test eax, eax + jns @f + neg eax + or bh, 2 +@@: + mov [esp+4], eax + mov bl, 3 + jmp .spec +.asterisk_precision: + cmp bl, 3 + jnz .errspec + mov [esp+8], eax + inc ebx + jmp .spec +.dot: + cmp bl, 2 + ja .errspec + mov bl, 3 + and dword [esp+8], 0 + jmp .spec +.long: + cmp bl, 3 + ja .errspec + mov bl, 4 + jmp .spec +.short: + cmp bl, 3 + ja .errspec + mov bl, 4 + or bh, 8 + jmp .spec +.unsigned: +.dec: + push 10 + jmp .write_number +.pointer: + mov dword [esp+12], 8 + or bh, 4 + and bh, not 8 +.hex: + push 16 + jmp @f +.oct: + push 8 +@@: + mov byte [esp+4], 0 +.write_number: + pop ecx + push edi + lea edi, [esp+16+64-1] ; edi -> end of buffer + mov byte [edi], 0 + push edx + push eax + mov eax, [ebp] + add ebp, 4 + test bh, 8 + jz @f + movzx eax, ax + cmp byte [esp], 'd' + jnz @f + movsx eax, ax +@@: + xor edx, edx + test eax, eax + jns @f + cmp byte [esp], 'd' + jnz @f + inc edx + neg eax +@@: + push edx + xor edx, edx +; зЁб«® ў eax, ®б­®ў ­ЁҐ бЁб⥬л бзЁб«Ґ­Ёп ў ecx +@@: + cmp dword [esp+16+8], 0 + jnz .print_num + test eax, eax + jz .zeronum +.print_num: + div ecx + xchg eax, edx + cmp al, 10 + sbb al, 69h + das + cmp byte [esp+4], 'x' + jnz @f + or al, 20h +@@: + dec edi + mov [edi], al + xor eax, eax + xchg eax, edx + test eax, eax + jnz .print_num +.zeronum: + push 0 + mov edx, [esp+12] + lea eax, [esp+32+64-1] + sub eax, edi + cmp dword [esp+20+8], -1 + jz .noprec1 + cmp eax, [esp+20+8] + jae .len_found1 + mov eax, [esp+20+8] + jmp .len_found1 +.noprec1: + test bh, 4 + jnz .do_print_num +.len_found1: + test bh, 2 + jnz .do_print_num + cmp byte [esp+20], 0 + jz @f + inc eax +@@: + cmp byte [esp+20], 0 + jnz @f + cmp byte [esp+4], 0 + jz @f + inc eax +@@: + test bh, 1 + jz .nosharp1 + cmp cl, 8 + jnz @f + inc eax + jmp .nosharp1 +@@: + cmp cl, 16 + jnz .nosharp1 + inc eax + inc eax +.nosharp1: + cmp dword [esp+20+4], -1 + jz .do_print_num + sub eax, [esp+20+4] + jae .do_print_num + push ecx + mov ecx, eax + mov al, ' ' +@@: + xchg edi, [esp+20] + call con.write_char_ex + inc dword [esp+24+12+64+28] + xchg edi, [esp+20] + inc dword [esp+4] + inc ecx + jnz @b + pop ecx +.do_print_num: + mov al, '-' + cmp byte [esp+4], 0 + jnz .write_sign + mov al, [esp+20] + test al, al + jz .sign_written +.write_sign: + call .num_write_char +.sign_written: + test bh, 1 + jz .nosharp2 + mov al, '0' + cmp cl, 8 + jz @f + cmp cl, 16 + jnz .nosharp2 + call .num_write_char + mov al, [esp+8] +@@: + call .num_write_char +.nosharp2: + lea ecx, [esp+32+64-1] + sub ecx, edi + cmp dword [esp+20+8], -1 + jz .noprec2 + sub ecx, [esp+20+8] + jmp .lead_zeroes +.noprec2: + test bh, 4 + jz .do_print_num2 + add ecx, [esp] + sub ecx, [esp+20+4] +.lead_zeroes: + jae .do_print_num2 +@@: + mov al, '0' + call .num_write_char + inc ecx + jnz @b +.do_print_num2: + mov al, [edi] + test al, al + jz .num_written + call .num_write_char + inc edi + jmp .do_print_num2 +.num_written: + pop ecx + mov edi, [esp+12] + cmp dword [esp+16+4], -1 + jz .num_written2 +@@: + cmp ecx, [esp+16+4] + jae .num_written2 + mov al, ' ' + call con.write_char + inc ecx + jmp @b +.num_written2: + add esp, 16 +.spec_done: + add esp, 12 + jmp .loop +.char: + mov ecx, [esp+4] + cmp ecx, -1 + jnz @f + inc ecx +@@: + test ecx, ecx + jnz @f + inc ecx +@@: + test bh, 2 + jnz .char_left_pad + mov al, ' ' + dec ecx + jz .nowidth + add [esp+12+64+28], ecx +@@: + call con.write_char + loop @b +.nowidth: + mov al, [ebp] + add ebp, 4 + jmp .percent +.char_left_pad: + mov al, [ebp] + add ebp, 4 + call con.write_char_ex + add [esp+12+64+28], ecx + dec ecx + jz .nowidth2 + mov al, ' ' +@@: + call con.write_char + loop @b +.nowidth2: + jmp .spec_done +.string: + push esi + mov esi, [ebp] + test esi, esi + jnz @f + mov esi, con.aNull +@@: + add ebp, 4 + or ecx, -1 +@@: + inc ecx + cmp byte [esi+ecx], 0 + jnz @b + cmp ecx, [esp+12] + jb @f + mov ecx, [esp+12] +@@: + test bh, 2 + jnz .write_string + cmp dword [esp+8], -1 + jz .write_string + push ecx + sub ecx, [esp+12] + jae .nospace + mov al, ' ' +@@: + call con.write_char + inc dword [esp+20+64+28] + inc ecx + jnz @b +.nospace: + pop ecx +.write_string: + jecxz .string_written + add dword [esp+16+64+28], ecx + push ecx +@@: + lodsb + call con.write_char_ex + loop @b + pop ecx +.string_written: + pop esi + test bh, 2 + jz .spec_done + cmp dword [esp+4], -1 + jz .spec_done + sub ecx, [esp+4] + jae .spec_done + mov al, ' ' +@@: + call con.write_char + inc dword [esp+12+64+28] + inc ecx + jnz @b + jmp .spec_done +.done: + add esp, 64 + popad + jmp con.update_screen +.num_write_char: + xchg edi, [esp+20] + call con.write_char_ex + inc dword [esp+24+12+64+28] + xchg edi, [esp+20] + inc dword [esp+4] + ret + +con.write: +; esi = string, ebx = length (ebx=-1 for ASCIIZ strings) + push edi + call con.get_data_ptr + test ebx, ebx + jz .done +.loop: + lodsb + cmp ebx, -1 + jnz @f + test al, al + jz .done +@@: + call con.write_char_ex +.next: + cmp ebx, -1 + jz .loop + dec ebx + jnz .loop +.done: + pop edi + jmp con.update_screen + +con.get_data_ptr: + mov edi, [con.cur_y] + imul edi, [con.scr_width] + add edi, [con.cur_x] + add edi, edi + add edi, [con.data] + ret + +con.write_char_ex: + test byte [con_flags+1], 1 + jz con.write_special_char + +con.write_char: + push eax + + mov eax, [con.cur_x] + cmp eax, [con.scr_width] + jb @f + and [con.cur_x], 0 + call con.newline +@@: + mov eax, [esp] + stosb + mov al, byte [con_flags] + stosb + + mov eax, [con.cur_x] + inc eax + mov [con.cur_x], eax + + pop eax + ret + +con.write_special_char: + cmp [con_esc], 0 + jnz .esc_mode +.normal_mode: + cmp al, 10 + jz .write_lf + cmp al, 13 + jz .write_cr + cmp al, 27 + jz .write_esc + cmp al, 8 + jz .write_bs + cmp al, 9 + jnz con.write_char +.write_tab: + mov al, ' ' + call con.write_char + test [con.cur_x], 7 + jnz .write_tab + ret +.write_cr: + and [con.cur_x], 0 + jmp con.get_data_ptr +.write_lf: + and [con.cur_x], 0 + jmp con.newline +.write_bs: + cmp [con.cur_x], 0 + jz @f + dec [con.cur_x] + dec edi + dec edi + ret +@@: + push eax + mov eax, [con.cur_y] + dec eax + js @f + mov [con.cur_y], eax + mov eax, [con.scr_width] + dec eax + mov [con.cur_x], eax + dec edi + dec edi +@@: + pop eax + ret +.write_esc: + mov [con_esc], 1 + mov [con_esc_attr_n], 1 + and [con_esc_attrs], 0 + ret +.esc_mode: + cmp [con_sci], 0 + jnz .esc_sci + cmp al, '[' + jnz @f + mov [con_sci], 1 + ret +@@: + push eax + mov al, 27 + call con.write_char + pop eax + jmp con.write_char +.esc_sci: +; this is real Esc sequence + cmp al, '?' ; DEC private mode (DECSET/DECRST sequences) + je .questionmark + cmp al, ';' + jz .next_arg + cmp al, '0' + jb .not_digit + cmp al, '9' + ja .not_digit + push eax ecx edx + sub al, '0' + movzx eax, al + mov ecx, [con_esc_attr_n] + mov edx, [con_esc_attrs+(ecx-1)*4] + lea edx, [edx*5] + lea edx, [edx*2+eax] + mov [con_esc_attrs+(ecx-1)*4], edx + pop edx ecx eax + ret +.questionmark: + push ecx + mov ecx, [con_esc_attr_n] + mov dword[con_esc_attrs+(ecx-1)*4], 0xffffffff + pop ecx +.next_arg: + push eax + mov eax, [con_esc_attr_n] + inc eax + cmp al, 4 + jbe @f + dec eax +@@: + mov [con_esc_attr_n], eax + and [con_esc_attrs+(eax-1)*4], 0 + pop eax + ret +.not_digit: + mov [con_esc], 0 + mov [con_sci], 0 ; in any case, leave Esc mode + cmp al, 'J' + jz .clear + cmp al, 'H' + jz .setcursor + cmp al, 'f' + jz .setcursor + cmp al, 'm' + jz .set_attr + cmp al, 'A' + jz .cursor_up + cmp al, 'B' + jz .cursor_down + cmp al, 'C' + jz .cursor_right + cmp al, 'D' + jz .cursor_left + cmp al, 'l' + je .dec_rst + cmp al, 'h' + je .dec_set + ret ; simply skip unknown sequences + +.dec_rst: + mov eax, [con_esc_attrs] + cmp eax, 0xffffffff + jne .no_dec_rst + mov eax, [con_esc_attrs+4] + cmp eax, 25 + je .hide_cursor +.no_dec_rst: + ret +.hide_cursor: + mov [con.cursor_height], 0 + ret + +.dec_set: + mov eax, [con_esc_attrs] + cmp eax, 0xffffffff + jne .no_dec_set + mov eax, [con_esc_attrs+4] + cmp eax, 25 + je .show_cursor +.no_dec_set: + ret + +.show_cursor: + mov [con.cursor_height], (15*font_height+50)/100 ; default height + ret +.clear: + mov eax, [con_esc_attrs] + test eax, eax + jz .clear_till_end_of_screen ; [0J (or [J) + dec eax + jz .clear_till_start_of_screen ; [1J + dec eax + je .cls ; [2J + ret ; unknown sequence + +.clear_till_end_of_screen: + push edi ecx + mov ecx, [con.scr_width] + imul ecx, [con.scr_height] + + mov edi, [con.cur_y] + imul edi, [con.scr_width] + add edi, [con.cur_x] + + sub ecx, edi + shl edi, 1 + add edi, [con.data] + mov ah, byte[con_flags] + mov al, ' ' + rep stosw + + and [con.cur_x], 0 + and [con.cur_y], 0 + pop ecx edi + ret + +.clear_till_start_of_screen: + push edi ecx + mov ecx, [con.cur_y] + imul ecx, [con.scr_width] + add ecx, [con.cur_x] + mov edi, [con.data] + mov ah, byte[con_flags] + mov al, ' ' + rep stosw + pop ecx edi + ret + +.cls: ; clear screen completely + push ecx + and [con.cur_x], 0 + and [con.cur_y], 0 + mov edi, [con.data] + push edi + mov ecx, [con.scr_width] + imul ecx, [con.scr_height] + mov ax, 0720h + rep stosw + pop edi ecx +.nosetcursor: + ret +.setcursor: + cmp [con_esc_attr_n], 2 + je @f + xor eax, eax + mov [con.cur_x], eax + mov [con.cur_y], eax + jmp .j_get_data +@@: + mov eax, [con_esc_attrs] + cmp eax, [con.scr_width] + jae @f + mov [con.cur_x], eax +@@: + mov eax, [con_esc_attrs+4] + cmp eax, [con.scr_height+4] + jae @f + mov [con.cur_y], eax +.j_get_data: + jmp con.get_data_ptr +.cursor_up: + cmp [con_esc_attr_n], 1 + jnz .nosetcursor + mov eax, [con.cur_y] + sub eax, [con_esc_attrs] + jnc @f + xor eax, eax +@@: + mov [con.cur_y], eax + jmp .j_get_data +.cursor_down: + cmp [con_esc_attr_n], 1 + jnz .nosetcursor + mov eax, [con.cur_y] + add eax, [con_esc_attrs] + cmp eax, [con.scr_height] + jb @f + mov eax, [con.scr_height] + dec eax +@@: + mov [con.cur_y], eax + jmp .j_get_data +.cursor_right: + cmp [con_esc_attr_n], 1 + jnz .nosetcursor + mov eax, [con.cur_x] + add eax, [con_esc_attrs] + cmp eax, [con.scr_width] + jb @f + mov eax, [con.scr_width] + dec eax +@@: + mov [con.cur_x], eax + jmp .j_get_data +.cursor_left: + cmp [con_esc_attr_n], 1 + jnz .nosetcursor + mov eax, [con.cur_x] + sub eax, [con_esc_attrs] + jnc @f + xor eax, eax +@@: + mov [con.cur_x], eax + jmp .j_get_data +.set_attr: + push eax ecx edx + xor ecx, ecx +.set_one_attr: + mov eax, [con_esc_attrs+ecx*4] + cmp al, 0 + jz .attr_normal + cmp al, 1 + jz .attr_bold + cmp al, 5 + jz .attr_bgr_bold + cmp al, 7 + jz .attr_reversed + + xor edx, edx + cmp al, 30 + jz .attr_color + mov dl, 4 + cmp al, 31 + jz .attr_color + mov dl, 2 + cmp al, 32 + jz .attr_color + mov dl, 6 + cmp al, 33 + jz .attr_color + mov dl, 1 + cmp al, 34 + jz .attr_color + mov dl, 5 + cmp al, 35 + jz .attr_color + mov dl, 3 + cmp al, 36 + jz .attr_color + mov dl, 7 + cmp al, 37 + jz .attr_color + + xor edx, edx + cmp al, 40 + jz .attr_bgr_color + mov dl, 0x40 + cmp al, 41 + jz .attr_bgr_color + mov dl, 0x20 + cmp al, 42 + jz .attr_bgr_color + mov dl, 0x60 + cmp al, 43 + jz .attr_bgr_color + mov dl, 0x10 + cmp al, 44 + jz .attr_bgr_color + mov dl, 0x50 + cmp al, 45 + jz .attr_bgr_color + mov dl, 0x30 + cmp al, 46 + jz .attr_bgr_color + mov dl, 0x70 + cmp al, 47 + jz .attr_bgr_color + + mov dl, 0x08 + cmp al, 90 + jz .attr_color + mov dl, 4 + 8 + cmp al, 91 + jz .attr_color + mov dl, 2 + 8 + cmp al, 92 + jz .attr_color + mov dl, 6 + 8 + cmp al, 93 + jz .attr_color + mov dl, 1 + 8 + cmp al, 94 + jz .attr_color + mov dl, 5 + 8 + cmp al, 95 + jz .attr_color + mov dl, 3 + 8 + cmp al, 96 + jz .attr_color + mov dl, 7 + 8 + cmp al, 97 + jz .attr_color + + mov dl, 0x80 + cmp al, 100 + jz .attr_bgr_color + mov dl, 0x80 + 0x40 + cmp al, 101 + jz .attr_bgr_color + mov dl, 0x80 + 0x20 + cmp al, 102 + jz .attr_bgr_color + mov dl, 0x80 + 0x60 + cmp al, 103 + jz .attr_bgr_color + mov dl, 0x80 + 0x10 + cmp al, 104 + jz .attr_bgr_color + mov dl, 0x80 + 0x50 + cmp al, 105 + jz .attr_bgr_color + mov dl, 0x80 + 0x30 + cmp al, 106 + jz .attr_bgr_color + mov dl, 0x80 + 0x70 + cmp al, 107 + jnz .attr_continue + +.attr_bgr_color: + mov eax, [con_flags] + and al, 0x0F + or al, dl + mov [con_flags], eax + jmp .attr_continue +.attr_color: + mov eax, [con_flags] + and al, 0xF0 + or al, dl + mov [con_flags], eax + jmp .attr_continue +.attr_normal: + mov byte [con_flags], 7 + jmp .attr_continue +.attr_reversed: + mov byte [con_flags], 0x70 + jmp .attr_continue +.attr_bold: + or byte [con_flags], 8 + jmp .attr_continue +.attr_bgr_bold: + or byte [con_flags], 0x80 +.attr_continue: + inc ecx + cmp ecx, [con_esc_attr_n] + jb .set_one_attr + pop edx ecx eax + ret + +con.newline: + mov eax, [con.cur_y] + inc eax + mov [con.cur_y], eax + cmp eax, [con.scr_height] + jb @f + call con.scr_scroll_up +@@: + call con.get_data_ptr + ret + +con.scr_scroll_up: + pushad + mov edi, [con.data] + mov esi, edi + add esi, [con.scr_width] + add esi, [con.scr_width] + dec [con.cur_y] + mov ecx, [con.scr_height] + dec ecx + imul ecx, [con.scr_width] + shr ecx, 1 + rep movsd + adc ecx, ecx + rep movsw + mov ax, 0x0720 + mov ecx, [con.scr_width] + rep stosw + popad + ret + +con.data2image: + pushad + mov edi, [con.image] + mov esi, [con.data] + mov eax, [con.wnd_ypos] + mul [con.scr_width] + add eax, [con.wnd_xpos] + lea esi, [esi+eax*2] + mov ecx, [con.wnd_height] +.lh: + push ecx + mov ecx, [con.wnd_width] +.lw: + push ecx edi + xor eax, eax + mov al, [esi+1] + push eax + and al, 0xF + mov ebx, eax ; 梥в ⥪бв  + pop eax + shr al, 4 + mov ebp, eax ; 梥в д®­  + sub ebx, ebp + lodsb + inc esi +if font_width > 8 + lea edx, [eax+eax+font] +else + lea edx, [eax+font] +end if +.sh: + mov ecx, [edx] +repeat font_width + shr ecx, 1 + sbb eax, eax + and eax, ebx + add eax, ebp + mov [edi+%-1], al +end repeat + mov eax, [con.wnd_width] +; imul eax, font_width +; add edi, eax +if font_width = 6 + lea eax, [eax*2+eax] + lea edi, [edi+eax*2] +else if font_width = 7 + lea edi, [edi+eax*8] + sub edi, eax +else if font_width = 8 + lea edi, [edi+eax*8] +else if font_width = 9 + lea edi, [edi+eax*8] + add edi, eax +else if font_width = 10 + lea eax, [eax*4+eax] + lea edi, [edi+eax*2] +else +Unknown font_width value! +end if +if font_width > 8 + add edx, 256*2 + cmp edx, font+256*2*font_height +else + add edx, 256 + cmp edx, font+256*font_height +end if + jb .sh + pop edi ecx + add edi, font_width + sub ecx, 1 + jnz .lw + mov eax, [con.wnd_width] + imul eax, (font_height-1)*font_width + add edi, eax + pop ecx + mov eax, [con.scr_width] + sub eax, [con.wnd_width] + lea esi, [esi+eax*2] + dec ecx + jnz .lh + mov eax, [con.cur_y] + sub eax, [con.wnd_ypos] + jb .nocursor + cmp eax, [con.wnd_height] + jae .nocursor + inc eax + mul [con.wnd_width] + imul eax, font_height*font_width + mov edx, [con.cur_x] + sub edx, [con.wnd_xpos] + jb .nocursor + cmp edx, [con.wnd_width] + jae .nocursor + inc edx + imul edx, font_width + add eax, edx + add eax, [con.image] + mov edx, [con.wnd_width] + imul edx, font_width + neg edx + mov ecx, [con.cursor_height] + jecxz .nocursor +.cursor_loop: + push ecx + mov ecx, font_width + add eax, edx + push eax +@@: + xor byte [eax-1], 7 + dec eax + loop @b + pop eax + pop ecx + loop .cursor_loop +.nocursor: + popad + ret + +con_exit: + + mov ah,[con.init_cmd] + test ah,ah + je .ret + + cmp byte [esp+4], 0 + jz .noexit + mov [con.thread_op], 1 + call con.wake + + ret 4 +.noexit: + push esi + mov esi, [con.title] + mov edx, con.finished_title + mov ecx, 255 + call .strcpy + mov esi, con.aFinished + call .strcpy + mov byte [edx], 0 + pop esi + and [con.cursor_height], 0 + push con.finished_title + call con_set_title + ret 4 +.strcpy: + jecxz .ret +@@: + lodsb + test al, al + jz .ret + mov [edx], al + inc edx + loop @b +.ret: + ret + +con_set_title: + mov eax, [esp+4] + mov [con.title], eax + mov [con.thread_op], 2 + call con.wake + ret 4 + +; int __stdcall con_kbhit(void); +con_kbhit: + test byte [con_flags+1], 2 + jnz @f + mov eax, [con.input_start] + cmp eax, [con.input_end] +@@: + setnz al + movzx eax, al + ret + +con.force_entered_char: + cmp [con.entered_char], -1 + jnz .ret + mov [con.thread_op], 4 + call con.wake + test byte [con_flags+1], 2 + jnz .ret +; wait for response + push ebx + push 5 + pop eax + push 2 + pop ebx +@@: + int 0x40 + cmp [con.entered_char], -1 + jz @b + pop ebx +.ret: + ret + +; int __stdcall con_getch(void); +con_getch: + call con_init_check + call con.force_entered_char + test byte [con_flags+1], 2 + jnz con_getch_closed + movzx eax, byte [con.entered_char] + sar [con.entered_char], 8 + mov byte [con.entered_char+1], 0xFF + test al, al + jz @f + mov byte [con.entered_char], 0xFF +@@: + ret + +con_getch_closed: + xor eax, eax + ret + +; int __stdcall con_getch2(void); +con_getch2: + call con_init_check + call con.force_entered_char + test byte [con_flags+1], 2 + jnz con_getch_closed + mov eax, 0xFFFF + xchg ax, [con.entered_char] + ret + +; char* __stdcall con_gets(char* str, int n); +con_gets: + pop eax + push 0 + push eax +; char* __stdcall con_gets2(con_gets2_callback callback, char* str, int n); +con_gets2: + call con_init_check + mov eax, [esp+8] ; str + pushad + mov esi, eax ; str + mov ebx, [esp+20h+12] ; n + sub ebx, 1 + jle .ret + mov byte [esi], 0 + xor ecx, ecx ; ¤«Ё­  㦥 ўўҐ¤с­­®© бва®ЄЁ + call con.get_data_ptr +.loop: + call con_getch2 + test al, al + jz .extended + cmp al, 8 + jz .backspace + cmp al, 27 + jz .esc + cmp al, 13 + jz .enter + cmp al, 9 + jz .tab + inc ecx + mov dl, al + call con.write_char_ex + push [con.cur_x] + push [con.cur_y] + push edi + push esi +@@: + lodsb + mov [esi-1], dl + mov dl, al + test al, al + jz @f + call con.write_char_ex + jmp @b +@@: + mov [esi], dl + pop esi + inc esi + pop edi + pop [con.cur_y] + pop [con.cur_x] +.update_screen_and_loop: + call con.update_screen + cmp ecx, ebx + jb .loop +.ret_us: + mov edx, [con.cur_x] +@@: + lodsb + test al, al + jz @f + inc edx + cmp edx, [con.scr_width] + jb @b + xor edx, edx + call con.newline + jmp @b +@@: + mov [con.cur_x], edx + call con.get_data_ptr + call con.update_screen + jmp .ret +.esc: + mov edx, [con.cur_x] +@@: + lodsb + test al, al + jz @f + inc edx + cmp edx, [con.scr_width] + jb @b + xor edx, edx + call con.newline + jmp @b +@@: + mov [con.cur_x], edx + call con.get_data_ptr + dec esi + xor ecx, ecx +@@: + mov byte [esi], 0 + cmp esi, [esp+20h+8] + jbe .update_screen_and_loop + mov al, 8 + call con.write_special_char + mov al, ' ' + call con.write_char + mov al, 8 + call con.write_special_char + dec esi + jmp @b +.delete: + cmp byte [esi], 0 + jz .loop + lodsb + call con.write_char_ex +.backspace: + cmp esi, [esp+20h+8] + jbe .loop + push esi + mov edx, [con.cur_x] +@@: + lodsb + test al, al + jz @f + inc edx + cmp edx, [con.scr_width] + jb @b + xor edx, edx + call con.newline + jmp @b +@@: + mov [con.cur_x], edx + call con.get_data_ptr + dec esi + mov al, 8 + call con.write_special_char + mov al, ' ' + call con.write_char + mov al, 8 + call con.write_special_char + mov dl, 0 +@@: + cmp esi, [esp] + jbe @f + mov al, 8 + call con.write_special_char + dec esi + xchg dl, [esi] + mov al, dl + call con.write_char + mov al, 8 + call con.write_special_char + jmp @b +@@: + pop esi + dec esi + mov [esi], dl + dec ecx + jmp .update_screen_and_loop +.enter: + mov edx, [con.cur_x] +@@: + lodsb + test al, al + jz @f + inc edx + cmp edx, [con.scr_width] + jb @b + xor edx, edx + call con.newline + jmp @b +@@: + mov [con.cur_x], edx + call con.get_data_ptr + mov al, 10 + mov [esi-1], al + mov byte [esi], 0 + call con.write_special_char + call con.update_screen + jmp .ret +.tab: + mov al, 0 + mov ah, 0xF +.extended: + test ah, ah + jz .closed + xchg al, ah + cmp al, 0x4B + jz .left + cmp al, 0x4D + jz .right + cmp al, 0x47 + jz .home + cmp al, 0x4F + jz .end + cmp al, 0x53 + jz .delete +; give control to callback function + cmp dword [esp+20h+4], 0 + jz .loop +; remember length of text before and length of text after +; and advance cursor to the end of line + push ecx + push eax + lea edx, [esi+1] +@@: + lodsb + test al, al + jz @f + call con.write_char_ex + jmp @b +@@: + sub esi, edx + pop eax + push esi + dec edx + sub edx, [esp+28h+8] + push edx + push esp ; ppos + mov ecx, [esp+30h+4] + lea edx, [esp+30h+12] + push edx ; pn + lea edx, [esp+34h+8] + push edx ; pstr + push eax ; keycode + call ecx + call con.get_data_ptr + dec eax + js .callback_nochange + jz .callback_del + dec eax + jz .callback_output +; callback returned 2 - exit + add esp, 12 + jmp .ret +.callback_nochange: +; callback returned 0 - string was not changed, only restore cursor position + pop esi + pop ecx + test ecx, ecx + jz .cncs +@@: + mov al, 8 + call con.write_special_char + loop @b +.cncs: + pop ecx + add esi, [esp+20h+8] + jmp .callback_done +.callback_del: +; callback returned 1 - string was changed, delete old string and output new + mov ecx, [esp+8] + test ecx, ecx + jz .cds +@@: + mov al, 8 + call con.write_special_char + mov al, ' ' + call con.write_char_ex + mov al, 8 + call con.write_special_char + loop @b +.cds: +.callback_output: +; callback returned 2 - string was changed, output new string + pop edx + pop esi + pop ecx + mov esi, [esp+20h+8] + xor ecx, ecx +@@: + lodsb + test al, al + jz @f + call con.write_char_ex + inc ecx + jmp @b +@@: + dec esi + push ecx + sub ecx, edx + jz .cos +@@: + mov al, 8 + call con.write_special_char + dec esi + loop @b +.cos: + pop ecx +.callback_done: + call con.update_screen + mov ebx, [esp+20h+12] + dec ebx + cmp ecx, ebx + jae .ret_us + jmp .loop +.left: + cmp esi, [esp+20h+8] + jbe .loop + dec esi + mov al, 8 + call con.write_special_char + jmp .update_screen_and_loop +.right: + cmp byte [esi], 0 + jz .loop + lodsb + call con.write_char_ex + jmp .update_screen_and_loop +.home: + cmp esi, [esp+20h+8] + jz .update_screen_and_loop + dec esi + mov al, 8 + call con.write_special_char + jmp .home +.end: + lodsb + test al, al + jz @f + call con.write_char_ex + jmp .end +@@: + dec esi + jmp .update_screen_and_loop +.closed: + and dword [esp+1Ch], 0 +.ret: + popad + ret 12 + +; void __stdcall con_cls(); +con_cls: + mov ah,[con.init_cmd] + test ah,ah + je cmd_init_no + + push edi + call con.write_special_char.cls + pop edi + call con.update_screen + + ret + + cmd_init_no: + + push con.title_init_console + push -1 + push -1 + push -1 + push -1 + + call con_init + + ret + +; void __stdcall con_get_cursor_pos(int* px, int* py); +con_get_cursor_pos: + push eax ecx + mov eax, [esp+12] + mov ecx, [con.cur_x] + mov [eax], ecx + mov eax, [esp+16] + mov ecx, [con.cur_y] + mov [eax], ecx + pop ecx eax + ret 8 + +; void __stdcall con_set_cursor_pos(int px, int py); +con_set_cursor_pos: + push eax + mov eax, [esp+8] + cmp eax, [con.scr_width] + jae @f + mov [con.cur_x], eax +@@: + mov eax, [esp+12] + cmp eax, [con.scr_height] + jae @f + mov [con.cur_y], eax +@@: + pop eax + call con.update_screen + ret 8 + +con.update_screen: + push eax + mov eax, [con.cur_y] + sub eax, [con.wnd_ypos] + jb .up + cmp eax, [con.wnd_height] + jb .done + mov eax, [con.cur_y] + sub eax, [con.wnd_height] + inc eax + jmp .set +.up: + mov eax, [con.cur_y] +.set: + mov [con.wnd_ypos], eax +.done: + pop eax + mov [con.thread_op], 3 + +con.wake: + pushad + mov al, [con.thread_op] + cmp al, byte [con.ipc_buf+0x10] + jz .ret +@@: + push 60 + pop eax + push 2 + pop ebx + mov ecx, [con.console_tid] + jecxz .ret + mov edx, con.thread_op + push 1 + pop esi + int 0x40 + test eax, eax + jz @f + push 5 + pop eax + mov bl, 1 + int 0x40 + jmp @b +@@: +.ret: + popad + ret + +; Џ®в®Є ®Є­  Є®­б®«Ё. ЋЎа Ў влў Ґв ўў®¤ Ё ўлў®¤. +con.thread: +; Џ®в®Є ॠЈЁагҐв ­  IPC, Є®в®а®Ґ ЁбЇ®«м§гҐвбп в®«мЄ® ¤«п в®Ј®, зв®Ўл ҐЈ® ¬®¦­® Ўл«® "а §Ўг¤Ёвм" + push 40 + pop eax + push 0x67 + pop ebx + int 0x40 + mov al, 60 + mov bl, 1 + mov ecx, con.ipc_buf + push 0x11 + pop edx + int 0x40 + mov al, 66 + mov bl, 1 + mov ecx, ebx + int 0x40 +con.redraw: + call con.draw_window +con.msg_loop: + cmp dword [con.bUpPressed], 0 + jnz .wait_timeout + push 10 + pop eax + jmp @f +.wait_timeout: + push 23 + pop eax + push 5 + pop ebx +@@: + int 0x40 + dec eax + jz con.redraw + dec eax + jz con.key + dec eax + jz con.button + cmp al, 4 + jz con.ipc + jmp con.mouse +con.button: +; we have only one button, close +con.thread_exit: + or byte [con_flags+1], 2 + and [con.console_tid], 0 + and [con.entered_char], 0 + or eax, -1 + int 0x40 +con.key: + mov al, 2 + int 0x40 + and eax, 0xffff ; supress scancodes +; ah = scancode + cmp ah, 0xE0 + jnz @f + mov [con.bWasE0], 1 + jmp con.msg_loop +@@: + shr eax, 8 + xchg ah, [con.bWasE0] + test al, al + jle con.msg_loop + cmp al, 0x1D + jz con.msg_loop + cmp al, 0x2A + jz con.msg_loop + cmp al, 0x36 + jz con.msg_loop + cmp al, 0x38 + jz con.msg_loop + cmp al, 0x3A + jz con.msg_loop + cmp al, 0x45 + jz con.msg_loop + cmp al, 0x46 + jz con.msg_loop + mov edx, eax + cmp dl, 0x4e + je .numpad + cmp dl, 0x4a + je .numpad + push 66 + pop eax + push 3 + pop ebx + int 0x40 ; eax = control key state + test dh, dh + jnz .extended + test al, 0x80 ; numlock + jnz .numlock + bt [scan_has_ascii], edx + jnc .extended + test al, 0x30 ; alt + jnz .extended + test al, 0x80 ; numlock + jz .no_numlock + .numlock: + cmp dl, 71 + jb .no_numlock + cmp dl, 83 + ja .no_numlock + .numpad: + mov dh, [con.extended_numlock+edx-71] + xchg dl, dh + jmp .gotcode + .no_numlock: +; key has ASCII code + push eax edx + push 2 + pop ecx + test al, 3 + jnz @f + dec ecx +@@: + push 26 + pop eax + mov bl, 2 + mov edx, con.kbd_layout + int 0x40 + pop edx eax + mov dh, [con.kbd_layout+edx] + test al, 0xC + jz @f + sub dh, 0x60 + jmp @f +.extended: + mov dh, 0 ; no ASCII code +@@: +; dh contains ASCII-code; now convert scancode to extended key code + mov ecx, con.extended_alt + test al, 0x30 + jnz .xlat + + mov ecx, con.extended_shift + test al, 3 + jnz .xlat + + mov ecx, con.extended_ctrl + test al, 0xC + jnz .xlat + + cmp dl, 28 + jne @f + shl dx, 8 + mov dl, 13 + jmp .gotcode +@@: + cmp dl, 53 + jne @f + shl dx, 8 + mov dl, '/' + jmp .gotcode +@@: + cmp dl, 55 + jne @f + shl dx, 8 + mov dl, '*' + jmp .gotcode +@@: + xchg dl, dh + cmp dh, 0x57 + jz @f + cmp dh, 0x58 + jnz .gotcode +@@: + add dh, 0x85-0x57 + jmp .gotcode +.xlat: + movzx eax, dl + mov dl, dh + mov dh, [eax+ecx] +.gotcode: + test dh, dh + jz con.msg_loop + cmp dh, 0x94 + jnz @f + mov dl, 0 +@@: +; dx contains full keycode + cmp [con.bGetchRequested], 0 + jz @f + mov [con.entered_char], dx + jmp con.msg_loop +@@: + mov eax, [con.input_end] + mov ecx, eax + add eax, 2 + cmp eax, con.input_buffer_end + jnz @f + mov eax, con.input_buffer +@@: + cmp eax, [con.input_start] + jnz @f +; buffer overflow, make beep and continue + push 55 + pop eax + mov ebx, eax + mov esi, con.beep + int 0x40 + jmp con.msg_loop +@@: + mov [ecx], dx + mov [con.input_end], eax + jmp con.msg_loop +con.ipc: + movzx eax, byte [con.ipc_buf+0x10] + mov byte [con.ipc_buf+4], 8 + mov byte [con.ipc_buf+0x10], 0 + dec eax + jz con.thread_exit + dec eax + jz con.set_title + dec eax + jz con.redraw_image + dec eax + jz con.getch + jmp con.msg_loop +con.set_title: + push 71 + pop eax + push 1 + pop ebx + mov ecx, [con.title] + int 0x40 + jmp con.msg_loop +con.redraw_image: + call con.data2image + call con.draw_image + jmp con.msg_loop +con.getch: + mov eax, [con.input_start] + cmp eax, [con.input_end] + jz .noinput + mov ecx, [eax] + mov [con.entered_char], cx + inc eax + inc eax + cmp eax, con.input_buffer_end + jnz @f + mov eax, con.input_buffer +@@: + mov [con.input_start], eax + jmp con.msg_loop +.noinput: + mov [con.bGetchRequested], 1 + jmp con.msg_loop +con.mouse: + push 37 + pop eax + push 7 + pop ebx + int 0x40 + test eax, eax + jz .no_scrollmouse + cwde + add eax, [con.wnd_ypos] + jg @f + xor eax, eax +@@: + mov ebx, [con.scr_height] + sub ebx, [con.wnd_height] + cmp eax, ebx + jb @f + mov eax, ebx +@@: + mov [con.wnd_ypos], eax + jmp con.redraw_image +.no_scrollmouse: + xor eax, eax + xchg eax, dword [con.bUpPressed] + mov dword [con.bUpPressed_saved], eax + push 37 + pop eax + push 2 + pop ebx + int 0x40 + test al, 1 + jnz @f + cmp [con.vscroll_pt], -1 + jz .redraw_if_needed + or [con.vscroll_pt], -1 +.redraw_if_needed: + cmp dword [con.bUpPressed_saved], 0 + jnz con.redraw_image + jmp con.msg_loop +@@: + mov al, 37 + dec ebx + int 0x40 + movsx ebx, ax + sar eax, 16 + cmp [con.vscroll_pt], -1 + jnz .vscrolling + test ebx, ebx + js .redraw_if_needed + sub ax, [con.data_width] + jb .redraw_if_needed + cmp eax, con.vscroll_width + jae .redraw_if_needed + cmp ebx, con.vscroll_btn_height + jb .up + sub bx, [con.data_height] + jae .redraw_if_needed + cmp bx, -con.vscroll_btn_height + jge .down + add bx, [con.data_height] + sub bx, word [con.vscrollbar_pos] + jl .vscroll_up + cmp bx, word [con.vscrollbar_size] + jl .vscroll +.vscroll_down: + cmp [con.bScrollingDown_saved], 0 + jz .vscroll_down_first + cmp [con.bScrollingDown_saved], 1 + jz .vscroll_down_wasfirst + mov [con.bScrollingDown], 2 +.vscroll_down_do: + mov eax, [con.wnd_ypos] + add eax, [con.wnd_height] + dec eax + mov ebx, [con.scr_height] + sub ebx, [con.wnd_height] + cmp eax, ebx + jb @f + mov eax, ebx +@@: + mov [con.wnd_ypos], eax + jmp con.redraw_image +.vscroll_down_first: + push 26 + pop eax + push 9 + pop ebx + int 0x40 + mov [con.scroll_down_first_time], eax + mov [con.bScrollingDown], 1 + jmp .vscroll_down_do +.vscroll_down_wasfirst: + push 26 + pop eax + push 9 + pop ebx + int 0x40 + sub eax, [con.scroll_down_first_time] + cmp eax, 25 + jb @f + mov [con.bScrollingDown], 2 + jmp .vscroll_down_do +@@: + mov [con.bScrollingDown], 1 + jmp con.msg_loop +.vscroll_up: + cmp [con.bScrollingUp_saved], 0 + jz .vscroll_up_first + cmp [con.bScrollingUp_saved], 1 + jz .vscroll_up_wasfirst + mov [con.bScrollingUp], 2 +.vscroll_up_do: + mov eax, [con.wnd_ypos] + inc eax + sub eax, [con.wnd_height] + jns @f + xor eax, eax +@@: + mov [con.wnd_ypos], eax + jmp con.redraw_image +.vscroll_up_first: + push 26 + pop eax + push 9 + pop ebx + int 0x40 + mov [con.scroll_up_first_time], eax + mov [con.bScrollingUp], 1 + jmp .vscroll_up_do +.vscroll_up_wasfirst: + push 26 + pop eax + push 9 + pop ebx + int 0x40 + sub eax, [con.scroll_up_first_time] + cmp eax, 25 + jb @f + mov [con.bScrollingUp], 2 + jmp .vscroll_up_do +@@: + mov [con.bScrollingUp], 1 + jmp con.msg_loop +.up: + cmp [con.bUpPressed_saved], 0 + jz .up_first + cmp [con.bUpPressed_saved], 1 + jz .up_wasfirst + mov [con.bUpPressed], 2 +.up_do: + mov eax, [con.wnd_ypos] + dec eax + js @f + mov [con.wnd_ypos], eax +@@: + jmp con.redraw_image +.up_first: + push 26 + pop eax + push 9 + pop ebx + int 0x40 + mov [con.up_first_time], eax + mov [con.bUpPressed], 1 + jmp .up_do +.up_wasfirst: + push 26 + pop eax + push 9 + pop ebx + int 0x40 + sub eax, [con.up_first_time] + cmp eax, 25 + jb @f + mov [con.bUpPressed], 2 + jmp .up_do +@@: + mov [con.bUpPressed], 1 + jmp con.msg_loop +.down: + cmp [con.bDownPressed_saved], 0 + jz .down_first + cmp [con.bDownPressed_saved], 1 + jz .down_wasfirst + mov [con.bDownPressed], 2 +.down_do: + mov eax, [con.scr_height] + sub eax, [con.wnd_height] + jbe con.redraw_image + cmp [con.wnd_ypos], eax + jae con.redraw_image + inc [con.wnd_ypos] + jmp con.redraw_image +.down_first: + push 26 + pop eax + push 9 + pop ebx + int 0x40 + mov [con.down_first_time], eax + mov [con.bDownPressed], 1 + jmp .down_do +.down_wasfirst: + push 26 + pop eax + push 9 + pop ebx + int 0x40 + sub eax, [con.down_first_time] + cmp eax, 25 + jb @f + mov [con.bDownPressed], 2 + jmp .down_do +@@: + mov [con.bDownPressed], 1 + jmp con.msg_loop +.vscroll: + mov [con.vscroll_pt], ebx + call con.draw_image + jmp con.msg_loop +.vscrolling: + sub ebx, [con.vscroll_pt] + sub ebx, con.vscroll_btn_height + jge @f + xor ebx, ebx +@@: + movzx eax, [con.data_height] + sub eax, 2*con.vscroll_btn_height + sub eax, [con.vscrollbar_size] + cmp ebx, eax + jb @f + lea ebx, [eax-1] +@@: + xchg eax, ebx + mov edx, [con.scr_height] + sub edx, [con.wnd_height] + inc edx + mul edx + div ebx + cmp [con.wnd_ypos], eax + jz con.msg_loop + mov [con.wnd_ypos], eax + jmp con.redraw_image + +con.draw_window: + push 12 + pop eax + xor ebx, ebx + inc ebx + int 0x40 + mov al, 48 + mov bl, 4 + int 0x40 + mov ebx, [con.def_wnd_x-2] + mov bx, word [con.wnd_width] + imul bx, font_width + add bx, 5+5-1 + mov ecx, [con.def_wnd_y-2] + mov cx, word [con.wnd_height] + imul cx, font_height + lea ecx, [ecx+eax+5-1] + mov edx, 0x74000000 + mov edi, [con.title] +; place for scrollbar + mov eax, [con.wnd_height] + cmp eax, [con.scr_height] + jae @f + add ebx, con.vscroll_width +@@: + xor eax, eax + int 0x40 + ;Leency{ + mov eax,9 + mov ebx,process_info_buffer + mov ecx,-1 + int 0x40 + mov eax,[ebx+70] + mov [window_status],eax + test [window_status],100b ; window is rolled up + jnz .exit + test [window_status],10b ; window is minimized to panel + jnz .exit + ;}Leency - I'm in diamond code... + call con.draw_image + +.exit: + push 12 + pop eax + push 2 + pop ebx + int 0x40 + + ret + +con.draw_image: + xor edx, edx + mov ecx, [con.wnd_width] + imul ecx, font_width + mov [con.data_width], cx + shl ecx, 16 + mov cx, word [con.wnd_height] + imul cx, font_height + mov [con.data_height], cx + mov ebx, [con.image] + push 65 + pop eax + xor ebp, ebp + mov edi, con.colors + push 8 + pop esi + int 0x40 + mov al, 7 + mov edx, [con.wnd_height] + cmp edx, [con.scr_height] + jae .skip_vscroll + push ecx + mov edx, ecx + xor dx, dx + mov ebx, con.vscroll_btn3 + cmp [con.bUpPressed], 0 + jnz @f + mov ebx, con.vscroll_btn1 +@@: + mov ecx, con.vscroll_width*65536 + con.vscroll_btn_height + int 0x40 + pop edx + sub dx, con.vscroll_btn_height + mov ebx, con.vscroll_btn4 + cmp [con.bDownPressed], 0 + jnz @f + mov ebx, con.vscroll_btn2 +@@: + int 0x40 + push edx +; ‚лзЁб«пҐ¬ ўлб®вг ЎҐЈг­Є  + mov ax, dx + sub eax, con.vscroll_btn_height + mov ecx, eax + mul [con.wnd_height] + div [con.scr_height] + cmp eax, 5 + jae @f + mov al, 5 +@@: +; eax = ўлб®в  ЎҐЈг­Є . ‚лзЁб«пҐ¬ Ї®«®¦Ґ­ЁҐ ЎҐЈг­Є  + mov [con.vscrollbar_size], eax + xchg eax, ecx + sub eax, ecx + mul [con.wnd_ypos] + mov ebx, [con.scr_height] + sub ebx, [con.wnd_height] + div ebx + pop edx + push edx +; ecx = ўлб®в  ЎҐЈг­Є , eax = Ї®«®¦Ґ­ЁҐ + add eax, con.vscroll_btn_height + mov [con.vscrollbar_pos], eax + mov ebx, con.vscroll_bgr2 + cmp [con.bScrollingUp], 0 + jnz @f + mov ebx, con.vscroll_bgr1 +@@: + mov ecx, con.vscroll_width*65536 + con.vscroll_bgr_height + push eax + push 7 + pop eax + mov dx, con.vscroll_btn_height + call .vpattern + mov dx, word [con.vscrollbar_pos] + add dx, word [con.vscrollbar_size] + mov cx, con.vscroll_bgr_height + mov ebx, con.vscroll_bgr2 + cmp [con.bScrollingDown], 0 + jnz @f + mov ebx, con.vscroll_bgr1 +@@: + call .vpattern + mov ecx, [con.vscrollbar_pos] + mov dx, cx + add ecx, [con.vscrollbar_size] + sub ecx, con.vscroll_bar_height3 + push ecx + mov ebx, con.vscroll_bar1 + mov ecx, con.vscroll_width*65536 + con.vscroll_bar_height1 + int 0x40 + add dx, cx + mov cx, con.vscroll_bar_height2 + mov ebx, con.vscroll_bar2 + call .vpattern + mov ebx, con.vscroll_bar3 + mov cx, con.vscroll_bar_height3 + int 0x40 +.skip_vscroll: + ret + +.vpattern: + push edx + add dx, cx + cmp dx, [esp+8] + pop edx + jbe @f + mov cx, [esp+4] + sub cx, dx + jz .ret +@@: + int 0x40 + add dx, cx + cmp dx, [esp+4] + jb .vpattern +.ret: + ret 4 + +align 4 +con.colors dd 0x000000, 0x000080, 0x008000, 0x008080 + dd 0x800000, 0x800080, 0x808000, 0xC0C0C0 + dd 0x808080, 0x0000FF, 0x00FF00, 0x00FFFF + dd 0xFF0000, 0xFF00FF, 0xFFFF00, 0xFFFFFF + +scan_has_ascii: + dd 11011111111111111111111111111110b + dd 00000010001111111111101111111111b + dd 00000000000000000000000000000000b + dd 0 + +con.extended_alt: + db 00h,01h,78h,79h,7Ah,7Bh,7Ch,7Dh,7Eh,7Fh,80h,81h,82h,83h,0Eh,0A5h + db 10h,11h,12h,13h,14h,15h,16h,17h,18h,19h,1Ah,1Bh,1Ch,00h,1Eh,1Fh + db 20h,21h,22h,23h,24h,25h,26h,27h,28h,29h,00h,2Bh,2Ch,2Dh,2Eh,2Fh + db 30h,31h,32h,33h,34h,35h,00h,37h,00h,39h,00h,68h,69h,6Ah,6Bh,6Ch + db 6Dh,6Eh,6Fh,70h,71h,00h,00h,97h,98h,99h,4Ah,9Bh,9Ch,9Dh,4Eh,9Fh + db 0A0h,0A1h,0A2h,0A3h,00h,00h,00h,8Bh,8Ch,00h,00h,00h,00h,00h,00h,00h + times 20h db 0 +con.extended_ctrl: + times 0Fh db %-1 + db 0x94 + times 2Bh db %-1 + db 5Eh,5Fh,60h,61h,62h,63h,64h,65h,66h,67h,00h,00h + db 77h,8Dh,84h,8Eh,73h,8Fh,74h,90h,75h,91h,76h,92h,93h,00h,00h,00h,89h,8Ah + times 0x80-0x59 db 0 +con.extended_shift: + times 3Bh db %-1 + db 54h,55h,56h,57h,58h,59h,5Ah,5Bh,5Ch,5Dh,00h,00h + db 47h,48h,49h,4Ah,4Bh,4Ch,4Dh,4Eh,4Fh,50h,51h,52h,53h,00h,00h,00h,87h,88h + times 0x80-0x59 db 0 +con.extended_numlock: + db '7', '8', '9', '-' + db '4', '5', '6', '+' + db '1', '2', '3' + db '0', '.' + +; ‚ ⥪г饩 ॠ«Ё§ жЁЁ §­ зҐ­Ёп Ї® 㬮«з ­Ёо в Є®ўл. +; ‚ Ўг¤г饬 ®­Ё, ў®§¬®¦­®, Ўг¤гв бзЁвлў вмбп Є Є Ї а ¬Ґвал Ё§ ini-д ©«  console.ini. +con.def_wnd_width dd 80 +con.def_wnd_height dd 25 +con.def_scr_width dd 80 +con.def_scr_height dd 300 +con.def_wnd_x dd 200 +con.def_wnd_y dd 50 + +con.init_cmd db 0 +con.title_init_console db "Console",0 + +struc process_info +{ + cpu_usage dd ? ; +0 + window_stack_position dw ? ; +4 + window_stack_value dw ? ; +6 + dw ? ; +8 + process_name rb 12 ; +10 + memory_start dd ? ; +22 + used_memory dd ? ; +26 + PID dd ? ; +30 + box.x dd ? ; +34 + box.y dd ? ; +38 + box.width dd ? ; +42 + box.height dd ? ; +46 + slot_state dw ? ; +50 + dw ? ; +52 + client_box.x dd ? ; +54 + client_box.y dd ? ; +58 + client_box.width dd ? ; +62 + client_box.height dd ? ; +66 + wnd_state db ? ; +70 + rb (1024-71) +} +process_info_buffer process_info +window_status rd 1 + +con.vscroll_pt dd -1 + +align 16 +EXPORTS: + dd szStart, START + dd szVersion, 0x00020008 + dd szcon_init, con_init + dd szcon_write_asciiz, con_write_asciiz + dd szcon_write_string, con_write_length + dd szcon_printf, con_printf + dd szcon_exit, con_exit + dd szcon_get_flags, con_get_flags + dd szcon_set_flags, con_set_flags + dd szcon_kbhit, con_kbhit + dd szcon_getch, con_getch + dd szcon_getch2, con_getch2 + dd szcon_gets, con_gets + dd szcon_gets2, con_gets2 + dd szcon_get_font_height, con_get_font_height + dd szcon_get_cursor_height,con_get_cursor_height + dd szcon_set_cursor_height,con_set_cursor_height + dd szcon_cls, con_cls + dd szcon_get_cursor_pos, con_get_cursor_pos + dd szcon_set_cursor_pos, con_set_cursor_pos + dd szcon_set_title, con_set_title + dd 0 + +con_flags dd 7 +con.cursor_height dd (15*font_height+50)/100 +con.input_start dd con.input_buffer +con.input_end dd con.input_buffer + +con_esc_attr_n dd 0 +con_esc_attrs dd 0,0,0,0 +con_esc db 0 +con_sci db 0 + +con.entered_char dw -1 +con.bGetchRequested db 0 +con.bWasE0 db 0 + +szStart db 'START',0 + +szcon_init db 'con_init',0 +szcon_write_asciiz db 'con_write_asciiz',0 +szcon_write_string db 'con_write_string',0 +szcon_printf db 'con_printf',0 +szcon_exit db 'con_exit',0 +szVersion db 'version',0 +szcon_get_flags db 'con_get_flags',0 +szcon_set_flags db 'con_set_flags',0 +szcon_kbhit db 'con_kbhit',0 +szcon_getch db 'con_getch',0 +szcon_getch2 db 'con_getch2',0 +szcon_gets db 'con_gets',0 +szcon_gets2 db 'con_gets2',0 +szcon_get_font_height db 'con_get_font_height',0 +szcon_get_cursor_height db 'con_get_cursor_height',0 +szcon_set_cursor_height db 'con_set_cursor_height',0 +szcon_cls db 'con_cls',0 +szcon_get_cursor_pos db 'con_get_cursor_pos',0 +szcon_set_cursor_pos db 'con_set_cursor_pos',0 +szcon_set_title db 'con_set_title',0 + +con.thread_err db 'Cannot create console thread!',13,10,0 +con.nomem_err db 'Not enough memory!',13,10,0 +con.aFinished db ' [Finished]',0 +con.aNull db '(null)',0 +con.beep db 0x90, 0x3C, 0x00 +con.ipc_buf dd 0,8,0,0 + db 0 + +section '.data' data readable writable align 16 + +con.finished_title rb 256 + +con.cur_x rd 1 +con.cur_y rd 1 +con.wnd_xpos rd 1 +con.wnd_ypos rd 1 + +con.wnd_width rd 1 +con.wnd_height rd 1 +con.scr_width rd 1 +con.scr_height rd 1 +con.title rd 1 +con.data rd 1 +con.image rd 1 +con.console_tid rd 1 +con.data_width rw 1 +con.data_height rw 1 +con.vscrollbar_size rd 1 +con.vscrollbar_pos rd 1 +con.up_first_time rd 1 +con.down_first_time rd 1 +con.scroll_up_first_time rd 1 +con.scroll_down_first_time rd 1 +con.bUpPressed_saved rb 1 +con.bDownPressed_saved rb 1 +con.bScrollingUp_saved rb 1 +con.bScrollingDown_saved rb 1 + +con.input_buffer rw 128 +con.input_buffer_end = $ + +con.kbd_layout rb 128 + +; 1 = exit, 2 = set title, 3 = redraw, 4 = getch +con.thread_op rb 1 +con.bUpPressed rb 1 +con.bDownPressed rb 1 +con.bScrollingUp rb 1 +con.bScrollingDown rb 1 + +con.stack rb 1024 +con.stack_top = $ diff --git a/programs/develop/libraries/console_coff/console_en.txt b/programs/develop/libraries/console_coff/console_en.txt new file mode 100644 index 0000000000..c91986a8c6 --- /dev/null +++ b/programs/develop/libraries/console_coff/console_en.txt @@ -0,0 +1,162 @@ +console.obj exports the following functions + +typedef unsigned long dword; /* 32-bit unsigned integer */ +typedef unsigned short word; /* 16-bit unsigned integer */ + +void __stdcall con_init(dword wnd_width, dword wnd_height, + dword scr_width, dword scr_height, const char* title); +Console initialization. Must be called only once. +wnd_width, wnd_height - width and height (in units of characters) of the visible region; +scr_width, scr_height - width and height (in units of characters) of console; +Any of these four parameters can be set to -1 (=0xFFFFFFFF) +to use the library's default values; +title - console window's caption. + +void __stdcall con_exit(bool bCloseWindow); +You should call this funstion at the end of the program. +If bCloseWindow is zero, the string "[Finished]" will be added to the caption of the window +and the console window will remain on the screen until the user +closes it. + +void __stdcall con_set_title(const char* title); +Set new window caption. + +void __stdcall con_write_asciiz(const char* string); +Display ASCIIZ-string to the console at the current position, shifting +the current position. + +void __stdcall con_write_string(const char* string, dword length); +Similar to con_write_asciiz, but length of the string must be given as a separate parameter + +int __cdecl con_printf(const char* format, ...) +Standard "printf" function from ANSI C. + +dword __stdcall con_get_flags(void); +Get output flags. +dword __stdcall con_set_flags(dword new_flags); +Set output flags. This function returns previous values. +Flags (bitmask): +/* text color */ +#define CON_COLOR_BLUE 0x01 +#define CON_COLOR_GREEN 0x02 +#define CON_COLOR_RED 0x04 +#define CON_COLOR_BRIGHT 0x08 +/* background color */ +#define CON_BGR_BLUE 0x10 +#define CON_BGR_GREEN 0x20 +#define CON_BGR_RED 0x40 +#define CON_BGR_BRIGHT 0x80 +/* output controls */ +#define CON_IGNORE_SPECIALS 0x100 +/* if this flag is cleared, function interprets special characters: +10 ('\n') - next line +13 ('\r') - carriage return +8 ('\b') - backspace +9 ('\t') - tab +27 ('\033' = '\x1B') - the beginning of Esc-sequences; +otherwise, these characters will be displayed like ordinary characters. */ +/* Supported Esc-sequences: + Esc[;;m - choice of character attributes: + You can specify one, two or three codes in any order; + 0 = normal mode (white on black) + 1 = bright selection + 5 = bright background + 7 = inverse mode (black on white) + 30 = black characters + 31 = red characters + 32 = green characters + 33 = brown characters + 34 = blue characters + 35 = purple characters + 36 = turqoise characters + 37 = white characters + 40 = black background + 41 = red background + 42 = green background + 43 = brown background + 44 = blue background + 45 = purple background + 46 = turqoise background + 47 = white background + The following sequences appeared in version 5 of library: + Esc[2J - clear screen, move cursor to upper left corner + Esc[;H = Esc[;f - + move cursor to , + Esc[A - move cursor to lines up + Esc[B - move cursor to lines down + Esc[C - move cursor to positions right + Esc[D - move cursor to positions left +*/ +/* signal "console closed"; appeared in version 6; + ignored by con_set_flags */ +#define CON_WINDOW_CLOSED 0x200 +The default value for flags = 7. (grey text on black background) + +int __stdcall con_get_font_height(void); +Get the height of the font. + +int __stdcall con_get_cursor_height(void); +Get the height of the cursor. +int __stdcall con_set_cursor_height(int new_height); +Set the height of the cursor. This function returns previous value. +An attempt to set the value out of the correct interval (from 0 to +font_height-1) is ignored. +Cursor with zero height isn't displayed. +Default value: - 15% from font height. + +int __stdcall con_getch(void); +Get one character from the keyboard. + +For normal characters function returns ASCII-code. For extended +characters (eg, Fx, and arrows), first function call returns 0 +and second call returns the extended code (similar to the DOS-function +input). Starting from version 7, after closing the console window, +this function returns 0. + +word __stdcall con_getch2(void); +Reads a character from the keyboard. Low byte contains the ASCII-code +(0 for extended characters), high byte - advanced code (like in BIOS +input functions). Starting from version 7, after closing the console +window, this function returns 0. + +int __stdcall con_kbhit(void); +Returns 1 if a key was pressed, 0 otherwise. To read pressed keys use +con_getch and con_getch2. Starting from version 6, after closing +the console window, this function returns 1. + +char* __stdcall con_gets(char* str, int n); +Reads a string from the keyboard. Reading is interrupted when got +"new line" character, or after reading the (n-1) characters (depending on +what comes first). In the first case the newline is also recorded in the +str. The acquired line is complemented by a null character. +Starting from version 6, the function returns a pointer to the entered +line if reading was successful, and NULL if the console window was closed. + +typedef int (__stdcall * con_gets2_callback)(int keycode, char** pstr, int* pn, int* ppos); +char* __stdcall con_gets2(con_gets2_callback callback, char* str, int n); +Con_gets completely analogous, except that when the user +press unrecognized key, it calls the specified callback-procedure +(which may, for example, handle up / down for history and tab to enter +autocompletion). You should pass to the procedure: key code and three pointers +- to the string, to the maximum length and to the current position. +function may change the contents of string and may change the string +itself (for example, to reallocate memory for increase the limit), +maximum length, and position of the line - pointers are passed for it. +Return value: 0 = line wasn't changed 1 = line changed, you should +remove old string and display new, 2 = line changed, it is necessary +to display it; 3 = immediately exit the function. +Starting from version 6, the function returns a pointer to the entered +line with the successful reading, and NULL if the console window was closed. + +void __stdcall con_cls(); +Clear screen and set cursor at upper left corner. + + +void __stdcall con_get_cursor_pos(int* px, int* py); +Wrote current (x) coordinate of cursor to *px, and (y) to *py. + +void __stdcall con_set_cursor_pos(int x, int y); +Set the cursor position to the specified coordinates. If any of the +parameters beyond the relevant range (from 0 to 1 scr_width- +for x, from 0 to 1 for scr_height-y, scr_width scr_height and were asked if +call con_init), then the corresponding coordinate of the cursor does not change. \ No newline at end of file diff --git a/programs/develop/libraries/console_coff/console_ru.txt b/programs/develop/libraries/console_coff/console_ru.txt new file mode 100644 index 0000000000..26ce0895fa --- /dev/null +++ b/programs/develop/libraries/console_coff/console_ru.txt @@ -0,0 +1,165 @@ +console.obj экспортирует следующие функции: + +typedef unsigned long dword; /* 32-битное беззнаковое целое */ +typedef unsigned short word; /* 16-битное беззнаковое целое */ + +void __stdcall con_init(dword wnd_width, dword wnd_height, + dword scr_width, dword scr_height, const char* title); +Инициализация консоли. Вызывается один раз в начале программы. +wnd_width, wnd_height - высота и ширина (в символах) видимой в окне консоли + области; +scr_width, scr_height - высота и ширина (в символах) всей консоли; +любые из первых 4 параметров могут быть установлены в -1 (=0xFFFFFFFF) + - использовать значения по умолчанию; +title - заголовок окна консоли. + +void __stdcall con_exit(bool bCloseWindow); +Вызывается при завершении программы. Если (байтовый) параметр bCloseWindow +нулевой, то окно консоли остаётся на экране до того момента, как пользователь +пожелает закрыть его, при этом к заголовку добавляется строка " [Finished]". + +void __stdcall con_set_title(const char* title); +Устанавливает новый заголовок окна консоли. + +void __stdcall con_write_asciiz(const char* string); +Выводит ASCIIZ-строку в консоль в текущую позицию, продвигает текущую позицию. + +void __stdcall con_write_string(const char* string, dword length); +Аналогично con_write_asciiz, но выводит ровно length символов. + +int __cdecl con_printf(const char* format, ...) +Стандартная printf из ANSI C. + +dword __stdcall con_get_flags(void); +Получает значение флагов вывода. +dword __stdcall con_set_flags(dword new_flags); +Устанавливает значение флагов вывода. Возвращает старое значение. +Флаги (битовая маска): +/* цвет текста */ +#define CON_COLOR_BLUE 1 +#define CON_COLOR_GREEN 2 +#define CON_COLOR_RED 4 +#define CON_COLOR_BRIGHT 8 +/* цвет фона */ +#define CON_BGR_BLUE 0x10 +#define CON_BGR_GREEN 0x20 +#define CON_BGR_RED 0x40 +#define CON_BGR_BRIGHT 0x80 +/* управление выводом */ +#define CON_IGNORE_SPECIALS 0x100 +/* Если флаг сброшен, функция интерпретирует специальные символы: + 10 ('\n') - перевод в начало следующей строки + 13 ('\r') - перевод в начало текущей строки + 8 ('\b') - забой (на символ назад) + 9 ('\t') - табуляция + 27 ('\033'='\x1B') - начало Esc-последовательности; +иначе выводит их как обычные символы. */ +/* Поддерживаемые Esc-последовательности: + Esc[;;m - выбор атрибутов символов: + можно указывать один, два или три кода в любом порядке; + 0 = нормальное изображение (белые символы на чёрном фоне) + 1 = выделение яркостью + 5 = яркий фон + 7 = реверсное изображение (чёрные символы на белом фоне) + 30 = чёрные символы + 31 = красные символы + 32 = зелёные символы + 33 = коричневые символы + 34 = синие символы + 35 = фиолетовые символы + 36 = бирюзовые символы + 37 = белые символы + 40 = чёрный фон + 41 = красный фон + 42 = зелёный фон + 43 = коричневый фон + 44 = синий фон + 45 = фиолетовый фон + 46 = бирюзовый фон + 47 = белый фон + Следующие последовательности появились в версии 5 библиотеки: + Esc[2J - очистить экран, переместить курсор в левый верхний угол + Esc[;H = Esc[;f - + установить курсор в позицию с координатами , + Esc[A - переместить курсор на строк вверх + Esc[B - переместить курсор на строк вниз + Esc[C - переместить курсор на позиций вправо + Esc[D - переместить курсор на позиций влево +*/ +/* сигнал о закрытии окна консоли; появился в версии 6 библиотеки; + флаг игнорируется функцией con_set_flags */ +#define CON_WINDOW_CLOSED 0x200 +Значение по умолчанию для флагов = 7. + +int __stdcall con_get_font_height(void); +Возвращает значение высоты шрифта. + +int __stdcall con_get_cursor_height(void); +Получает значение высоты курсора. +int __stdcall con_set_cursor_height(int new_height); +Устанавливает значение высоты курсора. Возвращает старое значение. +Попытка установить значение вне корректного интервала (от 0 до font_height-1) +игнорируется. +Курсор высоты 0 не отображается на экране. +Значение высоты по умолчанию - 15% от высоты шрифта. + +int __stdcall con_getch(void); +Считывает один символ с клавиатуры. +Для обычных символов возвращается ASCII-код. Для расширенных символов +(например, Fx и стрелочек) первый вызов функции возвращает 0, +а повторный вызов возвращает расширенный код (подобно DOS-функциям ввода). +Начиная с версии 7 библиотеки, после закрытия окна консоли возвращается +значение 0. + +word __stdcall con_getch2(void); +Считывает один символ с клавиатуры. Младший байт содержит ASCII-код клавиши +(0 для расширенных символов), старший - расширенный код +(подобно BIOS-функциям ввода). +Начиная с версии 7 библиотеки, после закрытия окна консоли возвращается +значение 0. + +int __stdcall con_kbhit(void); +Возвращает 1, если какая-то клавиша была нажата, 0 иначе. Для считывания +нажатой клавиши предназначены функции con_getch и con_getch2. +Начиная с версии 6 библиотеки, после закрытия окна консоли всегда возвращает 1. + +char* __stdcall con_gets(char* str, int n); +Считывает строку с клавиатуры. Ввод прерывается при поступлении символа +новой строки, а также по прочтении n-1 символа (в зависимости от того, что +произойдёт раньше). В первом случае символ новой строки также записывается в +str. Считанная строка дополняется нулевым символом. +Начиная с версии 6 библиотеки, функция возвращает указатель на введённую +строку при успешном чтении и NULL, если окно консоли было закрыто. До версии +6 возвращаемое значение было неопределено. + +typedef int (__stdcall * con_gets2_callback)(int keycode, char** pstr, int* pn, int* ppos); +char* __stdcall con_gets2(con_gets2_callback callback, char* str, int n); +Функция появилась в версии 4 библиотеки. +Полностью аналогична con_gets за исключением того, что когда пользователь +нажимает нераспознанную клавишу, вызывается указанная callback-процедура +(которая может, например, обрабатывать up/down для истории ввода и tab для +автодополнения). Процедуре передаётся код клавиши и три указателя - на строку, +на лимит и на текущую позицию в строке. Процедура может менять содержимое +строки и может менять саму строку (например, перераспределить память для +увеличения лимита), лимит, позицию в строке - для этого и передаются указатели. +Возвращаемое значение: 0=строка не менялась; 1=строка изменилась, необходимо +удалить старую и вывести новую; 2=строка изменилась, необходимо её вывести; +3=немедленно выйти из функции. +Начиная с версии 6 библиотеки, функция возвращает указатель на введённую +строку при успешном чтении и NULL, если окно консоли было закрыто. До версии +6 возвращаемое значение было неопределено. + +void __stdcall con_cls(); +Функция появилась в версии 5 библиотеки. +Очищает экран и переводит курсор в левый верхний угол. + +void __stdcall con_get_cursor_pos(int* px, int* py); +Функция появилась в версии 5 библиотеки. +Записывает в *px текущую координату курсора по оси x, в *py - по оси y. + +void __stdcall con_set_cursor_pos(int x, int y); +Функция появилась в версии 5 библиотеки. +Устанавливает курсор в позицию с указанными координатами. Если какой-то из +параметров выходит за пределы соответствующего диапазона (от 0 до scr_width-1 +для x, от 0 до scr_height-1 для y, scr_width и scr_height были заданы при +вызове con_init), то соответствующая координата курсора не меняется. diff --git a/programs/develop/libraries/console_coff/examples/Tupfile.lua b/programs/develop/libraries/console_coff/examples/Tupfile.lua new file mode 100644 index 0000000000..b34ba0b9da --- /dev/null +++ b/programs/develop/libraries/console_coff/examples/Tupfile.lua @@ -0,0 +1,2 @@ +if tup.getconfig("NO_FASM") ~= "" then return end +tup.foreach_rule("*.asm", "fasm %f %o " .. tup.getconfig("KPACK_CMD"), "%B") diff --git a/programs/develop/libraries/console_coff/examples/proc32.inc b/programs/develop/libraries/console_coff/examples/proc32.inc new file mode 100644 index 0000000000..23c56b03c1 --- /dev/null +++ b/programs/develop/libraries/console_coff/examples/proc32.inc @@ -0,0 +1,268 @@ + +; Macroinstructions for defining and calling procedures + +macro stdcall proc,[arg] ; directly call STDCALL procedure + { common + if ~ arg eq + reverse + pushd arg + common + end if + call proc } + +macro invoke proc,[arg] ; indirectly call STDCALL procedure + { common + if ~ arg eq + reverse + pushd arg + common + end if + call [proc] } + +macro ccall proc,[arg] ; directly call CDECL procedure + { common + size@ccall = 0 + if ~ arg eq + reverse + pushd arg + size@ccall = size@ccall+4 + common + end if + call proc + if size@ccall + add esp,size@ccall + end if } + +macro cinvoke proc,[arg] ; indirectly call CDECL procedure + { common + size@ccall = 0 + if ~ arg eq + reverse + pushd arg + size@ccall = size@ccall+4 + common + end if + call [proc] + if size@ccall + add esp,size@ccall + end if } + +macro proc [args] ; define procedure + { common + match name params, args> + \{ define@proc name, \{ prologue name,flag,parmbytes,localbytes,reglist \} + macro locals + \{ virtual at ebp-localbytes+current + macro label . \\{ deflocal@proc .,:, \\} + struc db [val] \\{ \common deflocal@proc .,db,val \\} + struc dw [val] \\{ \common deflocal@proc .,dw,val \\} + struc dp [val] \\{ \common deflocal@proc .,dp,val \\} + struc dd [val] \\{ \common deflocal@proc .,dd,val \\} + struc dt [val] \\{ \common deflocal@proc .,dt,val \\} + struc dq [val] \\{ \common deflocal@proc .,dq,val \\} + struc rb cnt \\{ deflocal@proc .,rb cnt, \\} + struc rw cnt \\{ deflocal@proc .,rw cnt, \\} + struc rp cnt \\{ deflocal@proc .,rp cnt, \\} + struc rd cnt \\{ deflocal@proc .,rd cnt, \\} + struc rt cnt \\{ deflocal@proc .,rt cnt, \\} + struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \} + macro endl + \{ purge label + restruc db,dw,dp,dd,dt,dq + restruc rb,rw,rp,rd,rt,rq + restruc byte,word,dword,pword,tword,qword + current = $-(ebp-localbytes) + end virtual \} + macro ret operand + \{ match any, operand \\{ retn operand \\} + match , operand \\{ match epilogue:reglist, epilogue@proc: + \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \} + macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2 + end if \} } + +macro defargs@proc [arg] + { common + if ~ arg eq + forward + local ..arg,current@arg + match argname:type, arg + \{ current@arg equ argname + label ..arg type + argname equ ..arg + if dqword eq type + dd ?,?,?,? + else if tbyte eq type + dd ?,?,? + else if qword eq type | pword eq type + dd ?,? + else + dd ? + end if \} + match =current@arg,current@arg + \{ current@arg equ arg + arg equ ..arg + ..arg dd ? \} + common + args@proc equ current@arg + forward + restore current@arg + common + end if } + +macro deflocal@proc name,def,[val] + { common + match vars, all@vars \{ all@vars equ all@vars, \} + all@vars equ all@vars name + forward + local ..var,..tmp + ..var def val + match =?, val \{ ..tmp equ \} + match any =dup (=?), val \{ ..tmp equ \} + match tmp : value, ..tmp : val + \{ tmp: end virtual + initlocal@proc ..var,def value + virtual at tmp\} + common + match first rest, ..var, \{ name equ first \} } + +macro initlocal@proc name,def + { virtual at name + def + size@initlocal = $ - name + end virtual + position@initlocal = 0 + while size@initlocal > position@initlocal + virtual at name + def + if size@initlocal - position@initlocal < 2 + current@initlocal = 1 + load byte@initlocal byte from name+position@initlocal + else if size@initlocal - position@initlocal < 4 + current@initlocal = 2 + load word@initlocal word from name+position@initlocal + else + current@initlocal = 4 + load dword@initlocal dword from name+position@initlocal + end if + end virtual + if current@initlocal = 1 + mov byte [name+position@initlocal],byte@initlocal + else if current@initlocal = 2 + mov word [name+position@initlocal],word@initlocal + else + mov dword [name+position@initlocal],dword@initlocal + end if + position@initlocal = position@initlocal + current@initlocal + end while } + +macro endp + { purge ret,locals,endl + finish@proc + purge finish@proc + restore regs@proc + match all,args@proc \{ restore all \} + restore args@proc + match all,all@vars \{ restore all \} } + +macro local [var] + { common + locals + forward done@local equ + match varname[count]:vartype, var + \{ match =BYTE, vartype \\{ varname rb count + restore done@local \\} + match =WORD, vartype \\{ varname rw count + restore done@local \\} + match =DWORD, vartype \\{ varname rd count + restore done@local \\} + match =PWORD, vartype \\{ varname rp count + restore done@local \\} + match =QWORD, vartype \\{ varname rq count + restore done@local \\} + match =TBYTE, vartype \\{ varname rt count + restore done@local \\} + match =DQWORD, vartype \\{ label varname dqword + rq count+count + restore done@local \\} + match , done@local \\{ virtual + varname vartype + end virtual + rb count*sizeof.\#vartype + restore done@local \\} \} + match :varname:vartype, done@local:var + \{ match =BYTE, vartype \\{ varname db ? + restore done@local \\} + match =WORD, vartype \\{ varname dw ? + restore done@local \\} + match =DWORD, vartype \\{ varname dd ? + restore done@local \\} + match =PWORD, vartype \\{ varname dp ? + restore done@local \\} + match =QWORD, vartype \\{ varname dq ? + restore done@local \\} + match =TBYTE, vartype \\{ varname dt ? + restore done@local \\} + match =DQWORD, vartype \\{ label varname dqword + dq ?,? + restore done@local \\} + match , done@local \\{ varname vartype + restore done@local \\} \} + match ,done@local + \{ var + restore done@local \} + common + endl } diff --git a/programs/develop/libraries/console_coff/examples/test_getch.asm b/programs/develop/libraries/console_coff/examples/test_getch.asm new file mode 100644 index 0000000000..100398b2ca --- /dev/null +++ b/programs/develop/libraries/console_coff/examples/test_getch.asm @@ -0,0 +1,168 @@ + +include 'proc32.inc' + +DLL_ENTRY equ 1 +DLL_EXIT equ -1 +REQ_DLL_VER equ 3 + +use32 + db 'MENUET01' + dd 1 + dd start + dd i_end + dd mem + dd mem + dd 0 + dd 0 + +start: + stdcall load_dll_and_import, dllname, imports + test eax, eax + jz exit + +; check version + cmp word [dll_ver], REQ_DLL_VER + jb exit + cmp word [dll_ver+2], REQ_DLL_VER + ja exit + push DLL_ENTRY + call [dll_start] + +; yes! Now do some work (getch() demo in this case). + + push caption + push -1 + push -1 + push -1 + push -1 + call [con_init] + +; C-equivalent of the following code: +; con_printf(start_string); +; int c; +; while ((c=con_getch())!=27) // Esc=exit +; { +; if (c) +; con_printf("normal character with code %d=0x%02X\n",c,c); +; else +; { +; c=con_getch(); +; con_printf("extended character with code %d=0x%02X\n",c,c); +; } +; } + push start_string + call [con_printf] + pop ecx +mainloop: + call [con_getch] + cmp al, 27 + jz done + test eax, eax + jz extended + push eax + push eax + push string_normal +@@: + call [con_printf] + add esp, 12 + jmp mainloop +extended: + call [con_getch] + test eax, eax + jz done + push eax + push eax + push string_extended + jmp @b +done: + push 1 + call [con_exit] +exit: + or eax, -1 + int 0x40 + +proc load_dll_and_import stdcall, _dllname:dword, _imports:dword + pushad +; load DLL + push 68 + pop eax + push 19 + pop ebx + mov ecx, [_dllname] + int 0x40 + test eax, eax + jz import_fail + +; initialize import + mov edi, eax + mov esi, [_imports] +import_loop: + lodsd + test eax, eax + jz import_done + mov edx, edi +import_find: + mov ebx, [edx] + test ebx, ebx + jz import_not_found + push eax +@@: + mov cl, [eax] + cmp cl, [ebx] + jnz import_find_next + test cl, cl + jz import_found + inc eax + inc ebx + jmp @b +import_find_next: + pop eax + add edx, 8 + jmp import_find +import_found: + pop eax + mov eax, [edx+4] + mov [esi-4], eax + jmp import_loop +import_not_found: +import_fail: + popad + xor eax, eax + ret +import_done: + popad + xor eax, eax + inc eax + ret +endp + +align 4 + +imports: +dll_start dd szStart +dll_ver dd szVersion +con_init dd szcon_init +con_printf dd szcon_printf +con_exit dd szcon_exit +con_getch dd szcon_getch + dd 0 + +szStart db 'START',0 +szVersion db 'version',0 +szcon_init db 'con_init',0 +szcon_printf db 'con_printf',0 +szcon_exit db 'con_exit',0 +szcon_getch db 'con_getch',0 + +dllname db '/sys/lib/console.obj',0 + +caption db 'Console test - getch()',0 +start_string db 'Press any key to see its code, or Esc to exit',10,0 +string_normal db 'normal character with code %d=0x%02X',10,0 +string_extended db 'extended character with code %d=0x%02X',10,0 + +i_end: + +align 4 +rb 2048 ; stack +mem: diff --git a/programs/develop/libraries/console_coff/examples/test_gets.asm b/programs/develop/libraries/console_coff/examples/test_gets.asm new file mode 100644 index 0000000000..9d3eb1fff6 --- /dev/null +++ b/programs/develop/libraries/console_coff/examples/test_gets.asm @@ -0,0 +1,156 @@ + +include 'proc32.inc' + +DLL_ENTRY equ 1 +DLL_EXIT equ -1 +REQ_DLL_VER equ 3 + +use32 + db 'MENUET01' + dd 1 + dd start + dd i_end + dd mem + dd mem + dd 0 + dd 0 + +start: + stdcall load_dll_and_import, dllname, imports + test eax, eax + jz exit + +; check version + cmp word [dll_ver], REQ_DLL_VER + jb exit + cmp word [dll_ver+2], REQ_DLL_VER + ja exit + push DLL_ENTRY + call [dll_start] + +; yes! Now do some work (gets() demo in this case). + + push caption + push -1 + push -1 + push -1 + push -1 + call [con_init] + +; C-equivalent of the following code: +; for (;;) +; { +; con_write_asciiz("Enter string (empty for exit): "); +; if (!con_gets(s,256)) break; +; if (s[0] == '\n') break; +; con_write_asciiz("You entered: "); +; con_write_asciiz(s); +; } +mainloop: + push str1 + call [con_write_asciiz] + push 256 + push s + call [con_gets] + test eax, eax + jz done + cmp [s], 10 + jz done + push str2 + call [con_write_asciiz] + push s + call [con_write_asciiz] + jmp mainloop +done: + push 1 + call [con_exit] +exit: + or eax, -1 + int 0x40 + +proc load_dll_and_import stdcall, _dllname:dword, _imports:dword + pushad +; load DLL + push 68 + pop eax + push 19 + pop ebx + mov ecx, [_dllname] + int 0x40 + test eax, eax + jz import_fail + +; initialize import + mov edi, eax + mov esi, [_imports] +import_loop: + lodsd + test eax, eax + jz import_done + mov edx, edi +import_find: + mov ebx, [edx] + test ebx, ebx + jz import_not_found + push eax +@@: + mov cl, [eax] + cmp cl, [ebx] + jnz import_find_next + test cl, cl + jz import_found + inc eax + inc ebx + jmp @b +import_find_next: + pop eax + add edx, 8 + jmp import_find +import_found: + pop eax + mov eax, [edx+4] + mov [esi-4], eax + jmp import_loop +import_not_found: +import_fail: + popad + xor eax, eax + ret +import_done: + popad + xor eax, eax + inc eax + ret +endp + +align 4 + +imports: +dll_start dd szStart +dll_ver dd szVersion +con_init dd szcon_init +con_write_asciiz dd szcon_write_asciiz +con_exit dd szcon_exit +con_gets dd szcon_gets + dd 0 + +szStart db 'START',0 +szVersion db 'version',0 +szcon_init db 'con_init',0 +szcon_write_asciiz db 'con_write_asciiz',0 +szcon_exit db 'con_exit',0 +szcon_gets db 'con_gets',0 + +dllname db '/sys/lib/console.obj',0 + +caption db 'Console test - gets()',0 +str1 db 'Enter string (empty for exit): ',0 +str2 db 'You entered: ',0 + +i_end: + +s rb 256 + +align 4 +rb 2048 ; stack +mem: diff --git a/programs/develop/libraries/console_coff/examples/test_gets2.asm b/programs/develop/libraries/console_coff/examples/test_gets2.asm new file mode 100644 index 0000000000..827743d03c --- /dev/null +++ b/programs/develop/libraries/console_coff/examples/test_gets2.asm @@ -0,0 +1,255 @@ + +include 'proc32.inc' + +DLL_ENTRY equ 1 +DLL_EXIT equ -1 +REQ_DLL_VER equ 4 + +use32 + db 'MENUET01' + dd 1 + dd start + dd i_end + dd mem + dd mem + dd 0 + dd 0 + +start: + stdcall load_dll_and_import, dllname, imports + test eax, eax + jz exit + +; check version + cmp word [dll_ver], REQ_DLL_VER + jb exit + cmp word [dll_ver+2], REQ_DLL_VER + ja exit + push DLL_ENTRY + call [dll_start] + +; yes! Now do some work (gets2() demo in this case). + + push caption + push 25 + push 80 + push 25 + push 80 + call [con_init] + +; C-equivalent of the following code: +; for (;;) +; { +; con_write_asciiz("Enter string (empty for exit): "); +; if (!con_gets2(mycallback,s,256)) break; +; if (s[0] == '\n') break; +; con_write_asciiz("You entered: "); +; con_write_asciiz(s); +; } +mainloop: + push str1 + call [con_write_asciiz] + push 256 + push s + push mycallback + call [con_gets2] + test eax, eax + jz done + cmp [s], 10 + jz done + push str2 + call [con_write_asciiz] + push s + call [con_write_asciiz] + jmp mainloop +done: + push 1 + call [con_exit] +exit: + or eax, -1 + int 0x40 + +proc mycallback stdcall, keycode:dword, pstr:dword, pn:dword, ppos:dword + mov eax, [keycode] + cmp al, 0x0F + jz .tab + cmp al, 0x3B + jz .f1 + cmp al, 0x48 + jz .up + cmp al, 0x50 + jz .down + xor eax, eax + ret +.tab: +; Tab pressed - insert "[autocomplete]" to current position + push esi edi + mov eax, [ppos] + mov eax, [eax] + mov ecx, [pn] + mov ecx, [ecx] + mov esi, [pstr] + mov esi, [esi] + add ecx, esi + add esi, eax + mov edx, esi +@@: + lodsb + test al, al + jnz @b + lea edi, [esi+str3.len] + cmp edi, ecx + jbe @f + mov edi, ecx + lea esi, [edi-str3.len] +@@: + cmp esi, edx + jbe @f + dec esi + dec edi + mov al, [esi] + mov [edi], al + jmp @b +@@: + cmp edi, ecx + jb @f + dec edi +@@: + mov ecx, edi + sub ecx, edx + mov edi, edx + mov esi, str3 + rep movsb + mov eax, [pstr] + sub edi, [eax] + mov eax, [ppos] + mov [eax], edi + pop edi esi + xor eax, eax + inc eax + ret +.f1: +; F1 pressed - say message + push str4 + call [con_write_asciiz] + push str1 + call [con_write_asciiz] + push 2 + pop eax + ret +.up: + push esi + mov esi, str5 + mov ecx, str5.len + jmp @f +.down: + push esi + mov esi, str6 + mov ecx, str6.len +@@: + push edi + mov edi, [pstr] + mov edi, [edi] + mov eax, [ppos] + mov [eax], ecx + rep movsb + xor eax, eax + stosb + pop edi esi + inc eax + ret +endp + +proc load_dll_and_import stdcall, _dllname:dword, _imports:dword + pushad +; load DLL + push 68 + pop eax + push 19 + pop ebx + mov ecx, [_dllname] + int 0x40 + test eax, eax + jz import_fail + +; initialize import + mov edi, eax + mov esi, [_imports] +import_loop: + lodsd + test eax, eax + jz import_done + mov edx, edi +import_find: + mov ebx, [edx] + test ebx, ebx + jz import_not_found + push eax +@@: + mov cl, [eax] + cmp cl, [ebx] + jnz import_find_next + test cl, cl + jz import_found + inc eax + inc ebx + jmp @b +import_find_next: + pop eax + add edx, 8 + jmp import_find +import_found: + pop eax + mov eax, [edx+4] + mov [esi-4], eax + jmp import_loop +import_not_found: +import_fail: + popad + xor eax, eax + ret +import_done: + popad + xor eax, eax + inc eax + ret +endp + +align 4 + +imports: +dll_start dd szStart +dll_ver dd szVersion +con_init dd szcon_init +con_write_asciiz dd szcon_write_asciiz +con_exit dd szcon_exit +con_gets2 dd szcon_gets2 + dd 0 + +szStart db 'START',0 +szVersion db 'version',0 +szcon_init db 'con_init',0 +szcon_write_asciiz db 'con_write_asciiz',0 +szcon_exit db 'con_exit',0 +szcon_gets2 db 'con_gets2',0 + +dllname db '/sys/lib/console.obj',0 + +caption db 'Console test - gets2()',0 +str1 db 'Enter string (empty for exit): ',0 +str2 db 'You entered: ',0 +str3 db '[autocomplete]' +str3.len = $ - str3 +str4 db 13,10,'Help? What help do you need?',13,10,0 +str5 db 'previous line in the history' +str5.len = $ - str5 +str6 db 'next line in the history' +str6.len = $ - str6 + +i_end: + +s rb 256 + +align 4 +rb 2048 ; stack +mem: diff --git a/programs/develop/libraries/console_coff/examples/testcon.asm b/programs/develop/libraries/console_coff/examples/testcon.asm new file mode 100644 index 0000000000..e868fadcee --- /dev/null +++ b/programs/develop/libraries/console_coff/examples/testcon.asm @@ -0,0 +1,58 @@ +use32 + db 'MENUET01' + dd 1 + dd start + dd i_end + dd mem + dd mem + dd 0 + dd 0 + +; useful includes +include '../../../../macros.inc' +purge mov,add,sub +include '../../../../proc32.inc' +include '../../../../dll.inc' + +start: +; First 3 steps are intended to load/init console DLL +; and are identical for all console programs + +; load DLL + stdcall dll.Load, @IMPORT + test eax, eax + jnz exit + +; yes! Now do some work (say helloworld in this case). + push caption + push -1 + push -1 + push -1 + push -1 + call [con_init] + push aHelloWorld + call [con_write_asciiz] + push 0 + call [con_exit] +exit: + or eax, -1 + int 0x40 + +caption db 'Console test',0 +aHelloWorld db 'Hello, World!',10,0 + +align 4 +@IMPORT: +library console, 'console.obj' +import console, \ + con_start, 'START', \ + con_init, 'con_init', \ + con_write_asciiz, 'con_write_asciiz', \ + con_exit, 'con_exit', \ + con_gets, 'con_gets' +i_end: + + +align 4 +rb 2048 ; stack +mem: diff --git a/programs/develop/libraries/console_coff/examples/testcon2_eng.asm b/programs/develop/libraries/console_coff/examples/testcon2_eng.asm new file mode 100644 index 0000000000..51410247e9 --- /dev/null +++ b/programs/develop/libraries/console_coff/examples/testcon2_eng.asm @@ -0,0 +1,161 @@ + +include 'proc32.inc' + +DLL_ENTRY equ 1 +DLL_EXIT equ -1 +REQ_DLL_VER equ 2 + +use32 + db 'MENUET01' + dd 1 + dd start + dd i_end + dd mem + dd mem + dd 0 + dd 0 + +start: + stdcall load_dll_and_import, dllname, imports + test eax, eax + jz exit + +; check version + cmp word [dll_ver], REQ_DLL_VER + jb exit + cmp word [dll_ver+2], REQ_DLL_VER + ja exit + push DLL_ENTRY + call [dll_start] + +; yes! Now do some work (show color strings in this case). + + push caption + push -1 + push -1 + push -1 + push -1 + call [con_init] +; C-equivalent of the following code: +; for (ebx=0;ebx<0x100;ebx++) +; { +; con_printf(t1,ebx); +; eax = con_set_flags(ebx); +; con_write_asciiz(text); +; con_set_flags(eax); +; } +; N.B. For efficiency result of first con_set_flags is not saved +; in register, but is pushed beforehand to the stack +; for second con_set_flags. +; Note that such code cannot be generated by stdcall macros. + xor ebx, ebx +@@: + push ebx + push t1 + call [con_printf] + add esp, 8 + push ebx + call [con_set_flags] + push eax + push text + call [con_write_asciiz] + call [con_set_flags] + inc bl + jnz @b + push text2 + call [con_write_asciiz] + push 0 + call [con_exit] +exit: + or eax, -1 + int 0x40 + +proc load_dll_and_import stdcall, _dllname:dword, _imports:dword + pushad +; load DLL + push 68 + pop eax + push 19 + pop ebx + mov ecx, [_dllname] + int 0x40 + test eax, eax + jz import_fail + +; initialize import + mov edi, eax + mov esi, [_imports] +import_loop: + lodsd + test eax, eax + jz import_done + mov edx, edi +import_find: + mov ebx, [edx] + test ebx, ebx + jz import_not_found + push eax +@@: + mov cl, [eax] + cmp cl, [ebx] + jnz import_find_next + test cl, cl + jz import_found + inc eax + inc ebx + jmp @b +import_find_next: + pop eax + add edx, 8 + jmp import_find +import_found: + pop eax + mov eax, [edx+4] + mov [esi-4], eax + jmp import_loop +import_not_found: +import_fail: + popad + xor eax, eax + ret +import_done: + popad + xor eax, eax + inc eax + ret +endp + +align 4 + +imports: +dll_start dd szStart +dll_ver dd szVersion +con_init dd szcon_init +con_write_asciiz dd szcon_write_asciiz +con_printf dd szcon_printf +con_set_flags dd szcon_set_flags +con_exit dd szcon_exit + dd 0 + +szStart db 'START',0 +szVersion db 'version',0 +szcon_init db 'con_init',0 +szcon_write_asciiz db 'con_write_asciiz',0 +szcon_printf db 'con_printf',0 +szcon_set_flags db 'con_set_flags',0 +szcon_exit db 'con_exit',0 + +dllname db '/sys/lib/console.obj',0 + +caption db 'Console test - colors',0 +t1 db 'Color 0x%02X: ',0 +text db 'This is sample text.',10,0 +text2 db 27,'[7mAnd this is an example of ' + db 27,'[1;36;41mEsc' + db 27,'[7m-sequences.',10,0 + +i_end: + +align 4 +rb 2048 ; stack +mem: diff --git a/programs/develop/libraries/console_coff/examples/testcon2_rus.asm b/programs/develop/libraries/console_coff/examples/testcon2_rus.asm new file mode 100644 index 0000000000..eb7f32a6b9 --- /dev/null +++ b/programs/develop/libraries/console_coff/examples/testcon2_rus.asm @@ -0,0 +1,161 @@ + +include 'proc32.inc' + +DLL_ENTRY equ 1 +DLL_EXIT equ -1 +REQ_DLL_VER equ 2 + +use32 + db 'MENUET01' + dd 1 + dd start + dd i_end + dd mem + dd mem + dd 0 + dd 0 + +start: + stdcall load_dll_and_import, dllname, imports + test eax, eax + jz exit + +; check version + cmp word [dll_ver], REQ_DLL_VER + jb exit + cmp word [dll_ver+2], REQ_DLL_VER + ja exit + push DLL_ENTRY + call [dll_start] + +; yes! Now do some work (show color strings in this case). + + push caption + push -1 + push -1 + push -1 + push -1 + call [con_init] +; C-equivalent of the following code: +; for (ebx=0;ebx<0x100;ebx++) +; { +; con_printf(t1,ebx); +; eax = con_set_flags(ebx); +; con_write_asciiz(text); +; con_set_flags(eax); +; } +; N.B. For efficiency result of first con_set_flags is not saved +; in register, but is pushed beforehand to the stack +; for second con_set_flags. +; Note that such code cannot be generated by stdcall macros. + xor ebx, ebx +@@: + push ebx + push t1 + call [con_printf] + add esp, 8 + push ebx + call [con_set_flags] + push eax + push text + call [con_write_asciiz] + call [con_set_flags] + inc bl + jnz @b + push text2 + call [con_write_asciiz] + push 0 + call [con_exit] +exit: + or eax, -1 + int 0x40 + +proc load_dll_and_import stdcall, _dllname:dword, _imports:dword + pushad +; load DLL + push 68 + pop eax + push 19 + pop ebx + mov ecx, [_dllname] + int 0x40 + test eax, eax + jz import_fail + +; initialize import + mov edi, eax + mov esi, [_imports] +import_loop: + lodsd + test eax, eax + jz import_done + mov edx, edi +import_find: + mov ebx, [edx] + test ebx, ebx + jz import_not_found + push eax +@@: + mov cl, [eax] + cmp cl, [ebx] + jnz import_find_next + test cl, cl + jz import_found + inc eax + inc ebx + jmp @b +import_find_next: + pop eax + add edx, 8 + jmp import_find +import_found: + pop eax + mov eax, [edx+4] + mov [esi-4], eax + jmp import_loop +import_not_found: +import_fail: + popad + xor eax, eax + ret +import_done: + popad + xor eax, eax + inc eax + ret +endp + +align 4 + +imports: +dll_start dd szStart +dll_ver dd szVersion +con_init dd szcon_init +con_write_asciiz dd szcon_write_asciiz +con_printf dd szcon_printf +con_set_flags dd szcon_set_flags +con_exit dd szcon_exit + dd 0 + +szStart db 'START',0 +szVersion db 'version',0 +szcon_init db 'con_init',0 +szcon_write_asciiz db 'con_write_asciiz',0 +szcon_printf db 'con_printf',0 +szcon_set_flags db 'con_set_flags',0 +szcon_exit db 'con_exit',0 + +dllname db '/sys/lib/console.obj',0 + +caption db 'Console test - colors',0 +t1 db '–ўҐв 0x%02X: ',0 +text db '‚®в ЇаЁ¬Ґа ⥪бв .',10,0 +text2 db 27,'[7mЂ нв® ЇаЁ¬Ґа ЁбЇ®«м§®ў ­Ёп ' + db 27,'[1;36;41mEsc' + db 27,'[7m-Ї®б«Ґ¤®ў вҐ«м­®б⥩.',10,0 + +i_end: + +align 4 +rb 2048 ; stack +mem: diff --git a/programs/develop/libraries/console_coff/font.inc b/programs/develop/libraries/console_coff/font.inc new file mode 100644 index 0000000000..4484fffde6 --- /dev/null +++ b/programs/develop/libraries/console_coff/font.inc @@ -0,0 +1,48 @@ +fontname equ 'font8x16.bmp' +virtual at 0 +file fontname, 3Eh +; sanity check +load a1 word from 0 +load a2 dword from 0xE +if (a1 <> 'BM') | (a2 <> 0x28) +error 'not BMP file!' +end if +load a1 dword from 0x12 +load a2 dword from 0x16 +if (a1 and 0xF) | (a2 and 0xF) | (a1 > 16*16) +error 'font: invalid width or height' +end if +font_width = a1 shr 4 +font_bmp_scanline = (font_width*2 + 3) and not 3 +font_height = a2 shr 4 +load a1 dword from 0x1A +if a1 <> 0x10001 +error 'font: not monochrome bitmap' +end if +end virtual + +font: +repeat font_height +cur_scan = % + repeat 256 + virtual at 0 + a2 = (font_width+14) shr 3 + if cur_scan=1 & %=0x10 + a2 = (font_width+7) shr 3 + end if + file fontname:3Eh + font_bmp_scanline*(font_height*(16-((%-1) shr 4))-cur_scan) + ((((%-1) and 0xF)*font_width) shr 3), a2 + dd 0 + load a1 dword from 0 + a1 = ((a1 and 0x55555555) shl 1) or ((a1 and 0xAAAAAAAA) shr 1) + a1 = ((a1 and 0x33333333) shl 2) or ((a1 and 0xCCCCCCCC) shr 2) + a1 = ((a1 and 0x0F0F0F0F) shl 4) or ((a1 and 0xF0F0F0F0) shr 4) + end virtual + a1 = (a1 shr (((%-1)*font_width) and 7)) and ((1 shl font_width) - 1) + a1 = a1 xor ((1 shl font_width) - 1) + if font_width > 8 + dw a1 + else + db a1 + end if + end repeat +end repeat diff --git a/programs/develop/libraries/console_coff/font8x16.bmp b/programs/develop/libraries/console_coff/font8x16.bmp new file mode 100644 index 0000000000..3928ccfd2a Binary files /dev/null and b/programs/develop/libraries/console_coff/font8x16.bmp differ