From fca4378433bc89736e0a870c86e3acef5ca6871a Mon Sep 17 00:00:00 2001 From: "Evgeny Grechnikov (Diamond)" Date: Sun, 27 Jul 2008 14:25:33 +0000 Subject: [PATCH] console library: upload sources git-svn-id: svn://kolibrios.org@836 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/develop/libraries/console/build.bat | 2 + .../develop/libraries/console/conscrl.inc | 45 + .../develop/libraries/console/conscrlv.bmp | Bin 0 -> 6006 bytes .../develop/libraries/console/console.asm | 2119 +++++++++++++++++ .../develop/libraries/console/console.txt | 114 + .../libraries/console/examples/proc32.inc | 268 +++ .../libraries/console/examples/test_getch.asm | 166 ++ .../libraries/console/examples/test_gets.asm | 154 ++ .../libraries/console/examples/testcon.asm | 106 + .../libraries/console/examples/testcon2.asm | 161 ++ .../console/examples/testcon2_eng.asm | 161 ++ programs/develop/libraries/console/font.inc | 48 + .../develop/libraries/console/font8x16.bmp | Bin 0 -> 4158 bytes 13 files changed, 3344 insertions(+) create mode 100644 programs/develop/libraries/console/build.bat create mode 100644 programs/develop/libraries/console/conscrl.inc create mode 100644 programs/develop/libraries/console/conscrlv.bmp create mode 100644 programs/develop/libraries/console/console.asm create mode 100644 programs/develop/libraries/console/console.txt create mode 100644 programs/develop/libraries/console/examples/proc32.inc create mode 100644 programs/develop/libraries/console/examples/test_getch.asm create mode 100644 programs/develop/libraries/console/examples/test_gets.asm create mode 100644 programs/develop/libraries/console/examples/testcon.asm create mode 100644 programs/develop/libraries/console/examples/testcon2.asm create mode 100644 programs/develop/libraries/console/examples/testcon2_eng.asm create mode 100644 programs/develop/libraries/console/font.inc create mode 100644 programs/develop/libraries/console/font8x16.bmp diff --git a/programs/develop/libraries/console/build.bat b/programs/develop/libraries/console/build.bat new file mode 100644 index 0000000000..b29ac6cbc7 --- /dev/null +++ b/programs/develop/libraries/console/build.bat @@ -0,0 +1,2 @@ +fasm console.asm ..\console.obj +e:\zhenya\program\menuet\kpack\kpack.exe ..\console.obj \ No newline at end of file diff --git a/programs/develop/libraries/console/conscrl.inc b/programs/develop/libraries/console/conscrl.inc new file mode 100644 index 0000000000..24944515cb --- /dev/null +++ b/programs/develop/libraries/console/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/conscrlv.bmp b/programs/develop/libraries/console/conscrlv.bmp new file mode 100644 index 0000000000000000000000000000000000000000..20b5b58e6d54e94bd6faaef6205f7b13602c19ee GIT binary patch literal 6006 zcmeI0v5vwp42HwZh)(bb_XNzR+j#^wcEob;!W%H~KsVoZ5)$GG%AZC!!Eur%=}=Xv zoYYP8*^!-CYQJ|sYt>&{^q*)SXnVAU+MrkJ3-4D;)A|8)hvTV6)ZhJazFf-$jy2zP z-S7V`SK!j}Fp+y%9!n?_?H>)Ei+fcAgH;F{ZpFR!Ukq#iWtk^R^SPO)`CuC#jUNs; zMax$b@q3kspothyuu**H7zy$W4w;a75f)9zytq_xu<`BuVGqS!7<0>&8^T>qDxO##&CR~8&X`TV>vGJ3r-$+BT%;fupZOkE$2$}u< z83M35)8|n?*qYtP#QKL6pJ4n5Hj3+(^q_wRhfK)42#Y3Uo|czX8b6`)gD>ga%jU1_ z=LIOe|Iun>BL9DqyWO8)x UAU*;&{yl%W#S`;w{;TTe6Y54ESpWb4 literal 0 HcmV?d00001 diff --git a/programs/develop/libraries/console/console.asm b/programs/develop/libraries/console/console.asm new file mode 100644 index 0000000000..228e880ed0 --- /dev/null +++ b/programs/develop/libraries/console/console.asm @@ -0,0 +1,2119 @@ +; ”г­ЄжЁЁ а Ў®вл б Є®­б®«мо ¤«п Їа®Ја ¬¬ Љ®«ЁЎаЁЋ‘ +; diamond, 2006, 2007 + + +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 68 + pop eax + push 11 + pop ebx + int 0x40 + 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 + mov ecx, 4 + mov eax, con.wnd_width + mov esi, con.def_wnd_width +.1: + cmp dword [eax], -1 + jnz @f + mov ebx, [esi] + mov [eax], ebx +@@: + add eax, 4 + add esi, 4 + loop .1 + push ebx +; 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 +; 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] + 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 + +; void __stdcall con_write_asciiz(const char* string); +con_write_asciiz: + 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: + 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 [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 + stosb + mov al, byte [con_flags] + stosb + mov eax, [con.cur_x] + inc eax + mov [con.cur_x], eax + cmp eax, [con.scr_width] + jb @f + and [con.cur_x], 0 + call con.newline +@@: + 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, ';' + 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 +.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, 'm' + jz .set_attr + ret ; simply skip unknown sequences +.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 + jnz .attr_continue +.attr_bgr_color: + mov eax, [con_flags] + and al, 0x8F + or al, dl + mov [con_flags], eax + jmp .attr_continue +.attr_color: + mov eax, [con_flags] + and al, 0xF8 + 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: + 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: + 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 +; 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.force_entered_char + 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 + +; int __stdcall con_getch2(void); +con_getch2: + call con.force_entered_char + mov eax, 0xFFFF + xchg ax, [con.entered_char] + ret + +; void __stdcall con_gets(char* str, int n); +con_gets: + pushad + mov esi, [esp+20h+4] ; str + mov ebx, [esp+20h+8] ; n + sub ebx, 1 + jle .ret + mov byte [esi], 0 + xor ecx, ecx ; ¤«Ё­  㦥 ўўҐ¤с­­®© бва®ЄЁ + call con.get_data_ptr +.loop: + call con_getch + test al, al + jz .extended + cmp al, 8 + jz .backspace + cmp al, 27 + jz .esc + cmp al, 13 + jz .enter + 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 + 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+4] + 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+4] + 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 +.extended: + call con_getch + 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 + jmp .loop +.left: + cmp esi, [esp+20h+4] + 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+4] + 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 +.ret: + popad + 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] + 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 eax, -1 + int 0x40 +con.key: + mov al, 2 + int 0x40 +; 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 + push 66 + pop eax + push 3 + pop ebx + int 0x40 ; eax = control key state + test dh, dh + jnz .extended + bt [scan_has_ascii], edx + jnc .extended + test al, 0x30 + jnz .extended +; 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 + 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: + 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, 0x33000000 + 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 + call con.draw_image + 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 + +; ‚ ⥪г饩 ॠ«Ё§ жЁЁ §­ зҐ­Ёп Ї® 㬮«з ­Ёо в Є®ўл. +; ‚ Ўг¤г饬 ®­Ё, ў®§¬®¦­®, Ўг¤гв бзЁвлў вмбп Є Є Ї а ¬Ґвал Ё§ 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.vscroll_pt dd -1 + +align 16 +EXPORTS: + dd szStart, START + dd szVersion, 0x00020003 + dd szcon_init, con_init + dd szcon_write_asciiz, con_write_asciiz + 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_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 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_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_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 + +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/console.txt b/programs/develop/libraries/console/console.txt new file mode 100644 index 0000000000..70ac5cf62f --- /dev/null +++ b/programs/develop/libraries/console/console.txt @@ -0,0 +1,114 @@ +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 = белый фон +*/ +Значение по умолчанию для флагов = 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-функциям ввода). + +word __stdcall con_getch2(void); +Считывает один символ с клавиатуры. Младший байт содержит ASCII-код клавиши +(0 для расширенных символов), старший - расширенный код +(подобно BIOS-функциям ввода). + +int __stdcall con_kbhit(void); +Возвращает 1, если какая-то клавиша была нажата, 0 иначе. Для считывания +нажатой клавиши предназначены функции con_getch и con_getch2. + +void __stdcall con_gets(char* str, int n); +Считывает строку с клавиатуры. Ввод прерывается при поступлении символа +новой строки, а также по прочтении n-1 символа (в зависимости от того, что +произойдёт раньше). В первом случае символ новой строки также записывается в +str. Считанная строка дополняется нулевым символом. diff --git a/programs/develop/libraries/console/examples/proc32.inc b/programs/develop/libraries/console/examples/proc32.inc new file mode 100644 index 0000000000..23c56b03c1 --- /dev/null +++ b/programs/develop/libraries/console/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/examples/test_getch.asm b/programs/develop/libraries/console/examples/test_getch.asm new file mode 100644 index 0000000000..7b6e6c2118 --- /dev/null +++ b/programs/develop/libraries/console/examples/test_getch.asm @@ -0,0 +1,166 @@ + +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] + 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/examples/test_gets.asm b/programs/develop/libraries/console/examples/test_gets.asm new file mode 100644 index 0000000000..542ebb6c55 --- /dev/null +++ b/programs/develop/libraries/console/examples/test_gets.asm @@ -0,0 +1,154 @@ + +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): "); +; con_gets(s,256); +; 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] + 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/examples/testcon.asm b/programs/develop/libraries/console/examples/testcon.asm new file mode 100644 index 0000000000..4fe66eaddc --- /dev/null +++ b/programs/develop/libraries/console/examples/testcon.asm @@ -0,0 +1,106 @@ +use32 + db 'MENUET01' + dd 1 + dd start + dd i_end + dd mem + dd mem + dd 0 + dd 0 + +REQ_DLL_VER = 2 +DLL_ENTRY = 1 + +start: +; First 3 steps are intended to load/init console DLL +; and are identical for all console programs + +; load DLL + mov eax, 68 + mov ebx, 19 + mov ecx, dll_name + int 0x40 + test eax, eax + jz exit + +; initialize import + mov edx, eax + mov esi, myimport +import_loop: + lodsd + test eax, eax + jz import_done + push edx +import_find: + mov ebx, [edx] + test ebx, ebx + jz exit;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 + pop edx + jmp import_loop +import_done: + +; 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 (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 + +dll_name db '/sys/lib/console.obj',0 +caption db 'Console test',0 +aHelloWorld db 'Hello, World!',10,0 + +align 4 +myimport: +dll_start dd aStart +dll_ver dd aVersion +con_init dd aConInit +con_write_asciiz dd aConWriteAsciiz +con_exit dd aConExit + dd 0 + +aStart db 'START',0 +aVersion db 'version',0 +aConInit db 'con_init',0 +aConWriteAsciiz db 'con_write_asciiz',0 +aConExit db 'con_exit',0 + +i_end: + +align 4 +rb 2048 ; stack +mem: diff --git a/programs/develop/libraries/console/examples/testcon2.asm b/programs/develop/libraries/console/examples/testcon2.asm new file mode 100644 index 0000000000..eb7f32a6b9 --- /dev/null +++ b/programs/develop/libraries/console/examples/testcon2.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/examples/testcon2_eng.asm b/programs/develop/libraries/console/examples/testcon2_eng.asm new file mode 100644 index 0000000000..51410247e9 --- /dev/null +++ b/programs/develop/libraries/console/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/font.inc b/programs/develop/libraries/console/font.inc new file mode 100644 index 0000000000..4484fffde6 --- /dev/null +++ b/programs/develop/libraries/console/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/font8x16.bmp b/programs/develop/libraries/console/font8x16.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3928ccfd2ae1da4504f8692ceaa9c96f3797ba53 GIT binary patch literal 4158 zcmcJSJCEc<5XaqeFgTi9UBX1mumLz+IV$NEOCUl-#8)7@53m6oRtILH73yHs!OGDI ziIfl_?W%=*4o;5IB|BPBXUwfS!8)M$SKG6X<8=pI+0)~ntK8Mqk8=Cn58kb;U#HL`!CuJYNdr-A+fSb}o zc*Wiy?}3k1=)JGR>DQvKX=tDq`)8@>N%VdN9`2@iUVHxo3|i)2@9d&}?!ymoXPAGv zgLYV4T#o!(alx#>5)kaUkOqo?qrhI&SB%R!vu=4nZP9`oX4>55;TCH*Xi|ep(oDO8 zH2Eqw#gONAY2_?Ez>sQK{eW&N=r%5t9kN)7T!|-+(lZ59_lP=-z z{G7XF%c37`M*aWH2o|9uXdF_!YDUy@K01AryoNIo?>M@?XT}*@!~VQ`boyFyt;YaK z1Es5?{r|^5ef1{l#Q1k`0r%g0^!Y7*75dpMQ?sngl$y(BO zFLlVWI_A4zqUXM+CJ`LeWu$1*G*cjM}KShQ<9*fY?FYS zSWo{*WiKyCemJk?uX*mAZYe?j(^;wuYOF_oBILhrX=!Pj1CRVT@sM}O|3hxB_zYa3 z_mB@^|9xh4%$J1x2R_TD{3-lirlF7d5f$e7hms$yJ&^o(gY84{5B;1P_)lF$ZR8ov zb#Znb(~DpI-S|_Q&Jz{KA70QfYa1I!)`B6zCo=vvV&o>yhsa9w$N7+D2tvf_#@5>9 zc}=-Y04;j`Y`FxB9<^CKzrSxt)Ka_D503MtJF&JK{m1#TR;gM``|`y&U$$XC|B{$^ zzMc%G`O}1n@m?3X;%Q!KJ=Yg2j}cXuvJbFDLtWvNsYr5@0uOy*^Oo>h_e|h0vb@$K zw<7~1+h*i&#FuPru_7>`cSPUrt@d;ZCQ`z2)=Qp*fcN6XHLoH^BiR-lMSPK>X2y9f z*g0%B5Ah~?W#X0AD_w_$!->ITw5_0CTOX{?u^TFES(J$2k8Gk|L$9K~jvT-eu@55` z2C>)0$_L{W>Z>t1biXp~h4pv$FiH&vevFbEkEZ#^9Uw&Rd6zG6?E0`PLp=3O4B~}~ z%Uf0noZXVSUZ6c2Lrytt*SNu|_tfr?Kk0vkZG%4WWEAxOKj7!4@+-vi1GZ$jA_|x1rx1nLd{Kz-1t@7skRk>>mWfsZMngS=uK(a8st4 zar4$oUTaF-OwGR|S1+(0b%_OTuqeqR)5Gr`*#mphVD=XFg!XBP9iDAQZiE&1_;^Ve zU*szsy0mp&DvW=V=cE1caS1&*lfdM8VbiDuk&*gO4!~Aex8fhJh4I4RjkHfWa_hw$ z?R&}aZkjhY0oQRVwUyFqt$SUwA290-1}6~pRJ0hr-jgp6!y$NRTiL2$9t>d+Mg>*y z3*QfFz!U*DJow!EPz-qOVQ1TO0EgD3=|F_%D=HKIpC1fx47L}BEuKB$T-kkl7eTYbQqQYE1#JP-Q;Yz__#7=&*ic25kkX(ncN zmNmCXu2GLhSyT!0*jTwY@}&LCzwP5&gIkPV-139p*mR_1-x{U-#hWf5H@lH{e|Frp z%3!_M9CU&ZG~J=%w)g5S2mx0(@8+zawg3PC literal 0 HcmV?d00001