Subversion Repositories Kolibri OS

Rev

Rev 6603 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ; ”㭪樨 à ¡®âë á ª®­á®«ìî ¤«ï ¯à®£à ¬¬ Š®«¨¡à¨Ž‘
  2. ; diamond, 2006-2008
  3.  
  4. format PE console 0.8 DLL at 7FEF0000h
  5.  
  6. section '.flat' code readable executable
  7.  
  8. include 'font.inc'
  9. include 'conscrl.inc'
  10. include '../../../export.inc'
  11.  
  12. ; ˆ­¨æ¨ «¨§ æ¨ï ª®­á®«¨
  13. ; void __stdcall con_init(dword wnd_width, dword wnd_height,
  14. ;       dword scr_width, dword scr_height, const char* title);
  15.  
  16. align 4
  17. con_init:
  18.         mov     [con_flags], 7
  19.         mov     [con.cursor_height], (15*font_height+50)/100
  20.         mov     [con.input_start], con.input_buffer
  21.         mov     [con.input_end], con.input_buffer
  22.         mov     [con.entered_char], -1
  23.  
  24.         pop     eax
  25.         pop     [con.wnd_width]
  26.         pop     [con.wnd_height]
  27.         pop     [con.scr_width]
  28.         pop     [con.scr_height]
  29.         pop     [con.title]
  30.         push    eax
  31.  
  32.         push ebx
  33.  
  34.                 mov [con.init_cmd],1
  35.  
  36.         mov     ecx, 4
  37.         mov     eax, con.wnd_width
  38.         mov     edx, con.def_wnd_width
  39. .1:
  40.         cmp     dword [eax], -1
  41.         jnz     @f
  42.         mov     ebx, [edx]
  43.         mov     [eax], ebx
  44. @@:
  45.         add     eax, 4
  46.         add     edx, 4
  47.         loop    .1
  48. ; allocate memory for console data & bitmap data
  49.         mov     eax, [con.scr_width]
  50.         mul     [con.scr_height]
  51.         lea     ecx, [eax+eax]
  52.         mov     eax, [con.wnd_width]
  53.         mul     [con.wnd_height]
  54.         imul    eax, font_width*font_height
  55.         mov     ebx, eax
  56.         push    ebx ecx
  57.         add     ecx, eax
  58.         push    68
  59.         pop     eax
  60.         push    12
  61.         pop     ebx
  62.         int     0x40
  63.         pop     ecx ebx
  64.         mov     edx, con.nomem_err
  65.         test    eax, eax
  66.         jz      con.fatal
  67.         mov     [con.data], eax
  68.         push    edi
  69.         mov     edi, eax
  70.         shr     ecx, 1
  71.         mov     ax, 0x0720
  72.         rep     stosw
  73.         mov     ecx, ebx
  74.         mov     [con.image], edi
  75.         xor     eax, eax
  76.         rep     stosb
  77.         pop     edi
  78.         and     byte [con_flags+1], not 2
  79. ; create console thread
  80.         push    51
  81.         pop     eax
  82.         xor     ebx, ebx
  83.         inc     ebx
  84.         mov     ecx, con.thread
  85.         mov     edx, con.stack_top
  86.         int     0x40
  87.         mov     edx, con.thread_err
  88.         test    eax, eax
  89.         js      con.fatal
  90.         mov     [con.console_tid], eax
  91.         pop     ebx
  92.         ret
  93. con.fatal:
  94. ; output string to debug board and die
  95.         mov     cl, [edx]
  96.         test    cl, cl
  97.         jz      @f
  98.         push    63
  99.         pop     eax
  100.         xor     ebx, ebx
  101.         inc     ebx
  102.         int     0x40
  103.         inc     edx
  104.         jmp     con.fatal
  105. @@:
  106.         or      eax, -1
  107.         int     0x40
  108.  
  109. ; dword __stdcall con_get_flags(void);
  110. con_get_flags:
  111.         mov     eax, [con_flags]
  112.         ret
  113.  
  114. ; dword __stdcall con_set_flags(dword flags);
  115. con_set_flags:
  116.         mov     eax, [esp+4]
  117.         and     ah, not 2
  118.         xchg    eax, [con_flags]
  119.         ret     4
  120.  
  121. ; dword __stdcall con_get_font_height(void);
  122. con_get_font_height:
  123.         mov     eax, font_height
  124.         ret
  125.  
  126. ; int __stdcall con_get_cursor_height(void);
  127. con_get_cursor_height:
  128.         mov     eax, [con.cursor_height]
  129.         ret
  130.  
  131. ; int __stdcall con_set_cursor_height(int new_height);
  132. con_set_cursor_height:
  133.         mov     eax, [esp+4]
  134.         cmp     eax, font_height
  135.         jae     @f
  136.         xchg    eax, [con.cursor_height]
  137.         ret     4
  138. @@:
  139.         mov     eax, [con.cursor_height]
  140.         ret     4
  141.  
  142. con_init_check:
  143.         mov ah,[con.init_cmd]
  144.         test ah,ah
  145.         jne cmd_init_yes
  146.  
  147.         push con.title_init_console
  148.         push -1
  149.         push -1
  150.         push -1
  151.         push -1
  152.  
  153.         call con_init
  154.  
  155.         cmd_init_yes:
  156.  
  157.         ret
  158. ; void __stdcall con_write_asciiz(const char* string);
  159. con_write_asciiz:
  160.                 call con_init_check
  161.         push    ebx esi
  162.         or      ebx, -1
  163.         mov     esi, [esp+12]
  164.         call    con.write
  165.         pop     esi ebx
  166.         ret     4
  167.  
  168. ; void __stdcall con_write_string(const char* string, dword length);
  169. con_write_length:
  170.         push    ebx esi
  171.         mov     esi, [esp+12]
  172.         mov     ebx, [esp+16]
  173.         call    con.write
  174.         pop     esi ebx
  175.         ret     8
  176.  
  177. ; Š ¦¤ë© ᨬ¢®« ª« áá¨ä¨æ¨àã¥âáï ª ª ®¤¨­ ¨§
  178. con.printfc.normal = 0   ; ­®à¬ «ì­ë© ᨬ¢®«
  179. con.printfc.percent = 1  ; '%'
  180. con.printfc.dot = 2      ; '.'
  181. con.printfc.asterisk = 3 ; '*'
  182. con.printfc.zero = 4     ; '0'
  183. con.printfc.digit = 5    ; ­¥­ã«¥¢ ï æ¨äà 
  184. con.printfc.plus = 6     ; '+'
  185. con.printfc.minus = 7    ; '-'
  186. con.printfc.sharp = 8    ; '#'
  187. con.printfc.space = 9    ; ' '
  188. con.printfc.long = 10    ; 'l' for 'long'
  189. con.printfc.short = 11   ; 'h' for 'short'
  190. con.printfc.dec = 12     ; 'd' = print decimal
  191. con.printfc.oct = 13     ; 'o' = print octal
  192. con.printfc.unsigned = 14 ; 'u' = print unsigned decimal
  193. con.printfc.hex = 15     ; 'x' = print hexadecimal
  194. con.printfc.pointer = 16 ; 'p' = print pointer
  195. con.printfc.char = 17    ; 'c' = print char
  196. con.printfc.string = 18  ; 's' = print string
  197.  
  198. macro set char,type
  199. {store byte con.printfc.#type at con.charcodes + char - ' '}
  200.  
  201. con.charcodes:
  202. times 'x'-' '+1         db      con.printfc.normal
  203.         set     '%', percent
  204.         set     '.', dot
  205.         set     '*', asterisk
  206.         set     '0', zero
  207.         set     '1', digit
  208.         set     '2', digit
  209.         set     '3', digit
  210.         set     '4', digit
  211.         set     '5', digit
  212.         set     '6', digit
  213.         set     '7', digit
  214.         set     '8', digit
  215.         set     '9', digit
  216.         set     ' ', space
  217.         set     '#', sharp
  218.         set     '+', plus
  219.         set     '-', minus
  220.         set     'X', hex
  221.         set     'x', hex
  222.         set     'c', char
  223.         set     'd', dec
  224.         set     'h', short
  225.         set     'i', dec
  226.         set     'l', long
  227.         set     'o', oct
  228.         set     'p', pointer
  229.         set     's', string
  230.         set     'u', unsigned
  231. purge set
  232. align 4
  233. con.charjump:
  234.         dd      con_printf.normal
  235.         dd      con_printf.percent
  236.         dd      con_printf.dot
  237.         dd      con_printf.asterisk
  238.         dd      con_printf.zero
  239.         dd      con_printf.digit
  240.         dd      con_printf.plus
  241.         dd      con_printf.minus
  242.         dd      con_printf.sharp
  243.         dd      con_printf.space
  244.         dd      con_printf.long
  245.         dd      con_printf.short
  246.         dd      con_printf.dec
  247.         dd      con_printf.oct
  248.         dd      con_printf.unsigned
  249.         dd      con_printf.hex
  250.         dd      con_printf.pointer
  251.         dd      con_printf.char
  252.         dd      con_printf.string
  253.  
  254. ; int __cdecl con_printf(const char* format, ...)
  255. con_printf:
  256.                 call con_init_check
  257.         xor     eax, eax
  258.         pushad
  259.         call    con.get_data_ptr
  260.         lea     ebp, [esp+20h+8]
  261.         mov     esi, [ebp-4]
  262.         sub     esp, 64         ; reserve space for buffer
  263. .loop:
  264.         xor     eax, eax
  265.         lodsb
  266.         test    al, al
  267.         jz      .done
  268.         cmp     al, '%'
  269.         jz      .spec_begin
  270. .normal:
  271.         call    con.write_char_ex
  272.         inc     dword [esp+64+28]
  273.         jmp     .loop
  274. .errspec:
  275. .percent:
  276.         add     esp, 12
  277.         jmp     .normal
  278. .spec_begin:
  279.         xor     ebx, ebx
  280. ; bl = ⨯ ¯®§¨æ¨¨:
  281. ; 0 = ­ ç «®
  282. ; 1 = ¯à®ç¨â ­ ¢¥¤ã騩 0 ¢ ᯥæ¨ä¨ª æ¨¨ ä®à¬ â 
  283. ; 2 = ç¨â ¥¬ ¯®«¥ è¨à¨­ë
  284. ; 3 = ç¨â ¥¬ ¯®«¥ â®ç­®áâ¨
  285. ; 4 = ¯à®ç¨â ­® ¯®«¥ à §¬¥à   à£ã¬¥­â 
  286. ; 5 = ç¨â ¥¬ ¯®«¥ ⨯ 
  287. ; bh = ä« £¨:
  288. ; 1 = ä« £ '#', ¢ë¢®¤¨âì 0/0x/0X
  289. ; 2 = ä« £ '-', ¢ëà ¢­¨¢ ­¨¥ ¢«¥¢®
  290. ; 4 = ä« £ '0', ¤®¯®«­¥­¨¥ ­ã«ï¬¨
  291. ; 8 = ä« £ 'h', ª®à®âª¨©  à£ã¬¥­â
  292.         push    -1
  293. ; dword [esp+8] = precision
  294.         push    -1
  295. ; dword [esp+4] = width
  296.         push    0
  297. ; byte [esp] = ä« £ 0/'+'/' '
  298. .spec:
  299.         xor     eax, eax
  300.         lodsb
  301.         test    al, al
  302.         jz      .done
  303.         cmp     al, ' '
  304.         jb      .normal
  305.         cmp     al, 'x'
  306.         ja      .normal
  307.         movzx   ecx, byte [con.charcodes + eax - ' ']
  308.         jmp     dword[con.charjump + ecx*4]
  309.  
  310. .sharp:
  311.         test    bl, bl
  312.         jnz     .errspec
  313.         or      bh, 1
  314.         jmp     .spec
  315. .minus:
  316.         test    bl, bl
  317.         jnz     .errspec
  318.         or      bh, 2
  319.         jmp     .spec
  320. .plus:
  321. .space:
  322.         test    bl, bl
  323.         jnz     .errspec
  324.         cmp     byte [esp], '+'
  325.         jz      .spec
  326.         mov     byte [esp], al
  327.         jmp     .spec
  328. .zero:
  329.         test    bl, bl
  330.         jnz     .digit
  331.         test    bh, 2
  332.         jnz     .spec
  333.         or      bh, 4
  334.         inc     ebx
  335.         jmp     .spec
  336. .digit:
  337.         sub     al, '0'
  338.         cmp     bl, 2
  339.         ja      .precision
  340.         mov     bl, 2
  341.         xchg    eax, [esp+4]
  342.         test    eax, eax
  343.         js      .spec
  344.         lea     eax, [eax*5]
  345.         add     eax, eax
  346.         add     [esp+4], eax
  347.         jmp     .spec
  348. .precision:
  349.         cmp     bl, 3
  350.         jnz     .errspec
  351.         xchg    eax, [esp+8]
  352.         lea     eax, [eax*5]
  353.         add     eax, eax
  354.         add     [esp+8], eax
  355.         jmp     .spec
  356. .asterisk:
  357.         mov     eax, [ebp]
  358.         add     ebp, 4
  359.         cmp     bl, 2
  360.         ja      .asterisk_precision
  361.         test    eax, eax
  362.         jns     @f
  363.         neg     eax
  364.         or      bh, 2
  365. @@:
  366.         mov     [esp+4], eax
  367.         mov     bl, 3
  368.         jmp     .spec
  369. .asterisk_precision:
  370.         cmp     bl, 3
  371.         jnz     .errspec
  372.         mov     [esp+8], eax
  373.         inc     ebx
  374.         jmp     .spec
  375. .dot:
  376.         cmp     bl, 2
  377.         ja      .errspec
  378.         mov     bl, 3
  379.         and     dword [esp+8], 0
  380.         jmp     .spec
  381. .long:
  382.         cmp     bl, 3
  383.         ja      .errspec
  384.         mov     bl, 4
  385.         jmp     .spec
  386. .short:
  387.         cmp     bl, 3
  388.         ja      .errspec
  389.         mov     bl, 4
  390.         or      bh, 8
  391.         jmp     .spec
  392. .unsigned:
  393. .dec:
  394.         push    10
  395.         jmp     .write_number
  396. .pointer:
  397.         mov     dword [esp+12], 8
  398.         or      bh, 4
  399.         and     bh, not 8
  400. .hex:
  401.         push    16
  402.         jmp     @f
  403. .oct:
  404.         push    8
  405. @@:
  406.         mov     byte [esp+4], 0
  407. .write_number:
  408.         pop     ecx
  409.         push    edi
  410.         lea     edi, [esp+16+64-1]      ; edi -> end of buffer
  411.         mov     byte [edi], 0
  412.         push    edx
  413.         push    eax
  414.         mov     eax, [ebp]
  415.         add     ebp, 4
  416.         test    bh, 8
  417.         jz      @f
  418.         movzx   eax, ax
  419.         cmp     byte [esp], 'd'
  420.         jnz     @f
  421.         movsx   eax, ax
  422. @@:
  423.         xor     edx, edx
  424.         test    eax, eax
  425.         jns     @f
  426.         cmp     byte [esp], 'd'
  427.         jnz     @f
  428.         inc     edx
  429.         neg     eax
  430. @@:
  431.         push    edx
  432.         xor     edx, edx
  433. ; ç¨á«® ¢ eax, ®á­®¢ ­¨¥ á¨á⥬ë áç¨á«¥­¨ï ¢ ecx
  434. @@:
  435.         cmp     dword [esp+16+8], 0
  436.         jnz     .print_num
  437.         test    eax, eax
  438.         jz      .zeronum
  439. .print_num:
  440.         div     ecx
  441.         xchg    eax, edx
  442.         cmp     al, 10
  443.         sbb     al, 69h
  444.         das
  445.         cmp     byte [esp+4], 'x'
  446.         jnz     @f
  447.         or      al, 20h
  448. @@:
  449.         dec     edi
  450.         mov     [edi], al
  451.         xor     eax, eax
  452.         xchg    eax, edx
  453.         test    eax, eax
  454.         jnz     .print_num
  455. .zeronum:
  456.         push    0
  457.         mov     edx, [esp+12]
  458.         lea     eax, [esp+32+64-1]
  459.         sub     eax, edi
  460.         cmp     dword [esp+20+8], -1
  461.         jz      .noprec1
  462.         cmp     eax, [esp+20+8]
  463.         jae     .len_found1
  464.         mov     eax, [esp+20+8]
  465.         jmp     .len_found1
  466. .noprec1:
  467.         test    bh, 4
  468.         jnz     .do_print_num
  469. .len_found1:
  470.         test    bh, 2
  471.         jnz     .do_print_num
  472.         cmp     byte [esp+20], 0
  473.         jz      @f
  474.         inc     eax
  475. @@:
  476.         cmp     byte [esp+20], 0
  477.         jnz     @f
  478.         cmp     byte [esp+4], 0
  479.         jz      @f
  480.         inc     eax
  481. @@:
  482.         test    bh, 1
  483.         jz      .nosharp1
  484.         cmp     cl, 8
  485.         jnz     @f
  486.         inc     eax
  487.         jmp     .nosharp1
  488. @@:
  489.         cmp     cl, 16
  490.         jnz     .nosharp1
  491.         inc     eax
  492.         inc     eax
  493. .nosharp1:
  494.         cmp     dword [esp+20+4], -1
  495.         jz      .do_print_num
  496.         sub     eax, [esp+20+4]
  497.         jae     .do_print_num
  498.         push    ecx
  499.         mov     ecx, eax
  500.         mov     al, ' '
  501. @@:
  502.         xchg    edi, [esp+20]
  503.         call    con.write_char_ex
  504.         inc     dword [esp+24+12+64+28]
  505.         xchg    edi, [esp+20]
  506.         inc     dword [esp+4]
  507.         inc     ecx
  508.         jnz     @b
  509.         pop     ecx
  510. .do_print_num:
  511.         mov     al, '-'
  512.         cmp     byte [esp+4], 0
  513.         jnz     .write_sign
  514.         mov     al, [esp+20]
  515.         test    al, al
  516.         jz      .sign_written
  517. .write_sign:
  518.         call    .num_write_char
  519. .sign_written:
  520.         test    bh, 1
  521.         jz      .nosharp2
  522.         mov     al, '0'
  523.         cmp     cl, 8
  524.         jz      @f
  525.         cmp     cl, 16
  526.         jnz     .nosharp2
  527.         call    .num_write_char
  528.         mov     al, [esp+8]
  529. @@:
  530.         call    .num_write_char
  531. .nosharp2:
  532.         lea     ecx, [esp+32+64-1]
  533.         sub     ecx, edi
  534.         cmp     dword [esp+20+8], -1
  535.         jz      .noprec2
  536.         sub     ecx, [esp+20+8]
  537.         jmp     .lead_zeroes
  538. .noprec2:
  539.         test    bh, 4
  540.         jz      .do_print_num2
  541.         add     ecx, [esp]
  542.         sub     ecx, [esp+20+4]
  543. .lead_zeroes:
  544.         jae     .do_print_num2
  545. @@:
  546.         mov     al, '0'
  547.         call    .num_write_char
  548.         inc     ecx
  549.         jnz     @b
  550. .do_print_num2:
  551.         mov     al, [edi]
  552.         test    al, al
  553.         jz      .num_written
  554.         call    .num_write_char
  555.         inc     edi
  556.         jmp     .do_print_num2
  557. .num_written:
  558.         pop     ecx
  559.         mov     edi, [esp+12]
  560.         cmp     dword [esp+16+4], -1
  561.         jz      .num_written2
  562. @@:
  563.         cmp     ecx, [esp+16+4]
  564.         jae     .num_written2
  565.         mov     al, ' '
  566.         call    con.write_char
  567.         inc     ecx
  568.         jmp     @b
  569. .num_written2:
  570.         add     esp, 16
  571. .spec_done:
  572.         add     esp, 12
  573.         jmp     .loop
  574. .char:
  575.         mov     ecx, [esp+4]
  576.         cmp     ecx, -1
  577.         jnz     @f
  578.         inc     ecx
  579. @@:
  580.         test    ecx, ecx
  581.         jnz     @f
  582.         inc     ecx
  583. @@:
  584.         test    bh, 2
  585.         jnz     .char_left_pad
  586.         mov     al, ' '
  587.         dec     ecx
  588.         jz      .nowidth
  589.         add     [esp+12+64+28], ecx
  590. @@:
  591.         call    con.write_char
  592.         loop    @b
  593. .nowidth:
  594.         mov     al, [ebp]
  595.         add     ebp, 4
  596.         jmp     .percent
  597. .char_left_pad:
  598.         mov     al, [ebp]
  599.         add     ebp, 4
  600.         call    con.write_char_ex
  601.         add     [esp+12+64+28], ecx
  602.         dec     ecx
  603.         jz      .nowidth2
  604.         mov     al, ' '
  605. @@:
  606.         call    con.write_char
  607.         loop    @b
  608. .nowidth2:
  609.         jmp     .spec_done
  610. .string:
  611.         push    esi
  612.         mov     esi, [ebp]
  613.         test    esi, esi
  614.         jnz     @f
  615.         mov     esi, con.aNull
  616. @@:
  617.         add     ebp, 4
  618.         or      ecx, -1
  619. @@:
  620.         inc     ecx
  621.         cmp     byte [esi+ecx], 0
  622.         jnz     @b
  623.         cmp     ecx, [esp+12]
  624.         jb      @f
  625.         mov     ecx, [esp+12]
  626. @@:
  627.         test    bh, 2
  628.         jnz     .write_string
  629.         cmp     dword [esp+8], -1
  630.         jz      .write_string
  631.         push    ecx
  632.         sub     ecx, [esp+12]
  633.         jae     .nospace
  634.         mov     al, ' '
  635. @@:
  636.         call    con.write_char
  637.         inc     dword [esp+20+64+28]
  638.         inc     ecx
  639.         jnz     @b
  640. .nospace:
  641.         pop     ecx
  642. .write_string:
  643.         jecxz   .string_written
  644.         add     dword [esp+16+64+28], ecx
  645.         push    ecx
  646. @@:
  647.         lodsb
  648.         call    con.write_char_ex
  649.         loop    @b
  650.         pop     ecx
  651. .string_written:
  652.         pop     esi
  653.         test    bh, 2
  654.         jz      .spec_done
  655.         cmp     dword [esp+4], -1
  656.         jz      .spec_done
  657.         sub     ecx, [esp+4]
  658.         jae     .spec_done
  659.         mov     al, ' '
  660. @@:
  661.         call    con.write_char
  662.         inc     dword [esp+12+64+28]
  663.         inc     ecx
  664.         jnz     @b
  665.         jmp     .spec_done
  666. .done:
  667.         add     esp, 64
  668.         popad
  669.         jmp     con.update_screen
  670. .num_write_char:
  671.         xchg    edi, [esp+20]
  672.         call    con.write_char_ex
  673.         inc     dword [esp+24+12+64+28]
  674.         xchg    edi, [esp+20]
  675.         inc     dword [esp+4]
  676.         ret
  677.  
  678. con.write:
  679. ; esi = string, ebx = length (ebx=-1 for ASCIIZ strings)
  680.         push    edi
  681.         call    con.get_data_ptr
  682.         test    ebx, ebx
  683.         jz      .done
  684. .loop:
  685.         lodsb
  686.         cmp     ebx, -1
  687.         jnz     @f
  688.         test    al, al
  689.         jz      .done
  690. @@:
  691.         call    con.write_char_ex
  692. .next:
  693.         cmp     ebx, -1
  694.         jz      .loop
  695.         dec     ebx
  696.         jnz     .loop
  697. .done:
  698.         pop     edi
  699.         jmp     con.update_screen
  700.  
  701. con.get_data_ptr:
  702.         mov     edi, [con.cur_y]
  703.         imul    edi, [con.scr_width]
  704.         add     edi, [con.cur_x]
  705.         add     edi, edi
  706.         add     edi, [con.data]
  707.         ret
  708.  
  709. con.write_char_ex:
  710.         test    byte [con_flags+1], 1
  711.         jz      con.write_special_char
  712.  
  713. con.write_char:
  714.         push    eax
  715.  
  716.         mov     eax, [con.cur_x]
  717.         cmp     eax, [con.scr_width]
  718.         jb      @f
  719.         and     [con.cur_x], 0
  720.         call    con.newline
  721. @@:
  722.         mov     eax, [esp]
  723.         stosb
  724.         mov     al, byte [con_flags]
  725.         stosb
  726.  
  727.         mov     eax, [con.cur_x]
  728.         inc     eax
  729.         mov     [con.cur_x], eax
  730.  
  731.         pop     eax
  732.         ret
  733.  
  734. con.write_special_char:
  735.         cmp     [con_esc], 0
  736.         jnz     .esc_mode
  737. .normal_mode:
  738.         cmp     al, 10
  739.         jz      .write_lf
  740.         cmp     al, 13
  741.         jz      .write_cr
  742.         cmp     al, 27
  743.         jz      .write_esc
  744.         cmp     al, 8
  745.         jz      .write_bs
  746.         cmp     al, 9
  747.         jnz     con.write_char
  748. .write_tab:
  749.         mov     al, ' '
  750.         call    con.write_char
  751.         test    [con.cur_x], 7
  752.         jnz     .write_tab
  753.         ret
  754. .write_cr:
  755.         and     [con.cur_x], 0
  756.         jmp     con.get_data_ptr
  757. .write_lf:
  758.         and     [con.cur_x], 0
  759.         jmp     con.newline
  760. .write_bs:
  761.         cmp     [con.cur_x], 0
  762.         jz      @f
  763.         dec     [con.cur_x]
  764.         dec     edi
  765.         dec     edi
  766.         ret
  767. @@:
  768.         push    eax
  769.         mov     eax, [con.cur_y]
  770.         dec     eax
  771.         js      @f
  772.         mov     [con.cur_y], eax
  773.         mov     eax, [con.scr_width]
  774.         dec     eax
  775.         mov     [con.cur_x], eax
  776.         dec     edi
  777.         dec     edi
  778. @@:
  779.         pop     eax
  780.         ret
  781. .write_esc:
  782.         mov     [con_esc], 1
  783.         mov     [con_esc_attr_n], 1
  784.         and     [con_esc_attrs], 0
  785.         ret
  786. .esc_mode:
  787.         cmp     [con_sci], 0
  788.         jnz     .esc_sci
  789.         cmp     al, '['
  790.         jnz     @f
  791.         mov     [con_sci], 1
  792.         ret
  793. @@:
  794.         push    eax
  795.         mov     al, 27
  796.         call    con.write_char
  797.         pop     eax
  798.         jmp     con.write_char
  799. .esc_sci:
  800. ; this is real Esc sequence
  801.         cmp     al, '?'         ; DEC private mode (DECSET/DECRST sequences)
  802.         je      .questionmark
  803.         cmp     al, ';'
  804.         jz      .next_arg
  805.         cmp     al, '0'
  806.         jb      .not_digit
  807.         cmp     al, '9'
  808.         ja      .not_digit
  809.         push    eax ecx edx
  810.         sub     al, '0'
  811.         movzx   eax, al
  812.         mov     ecx, [con_esc_attr_n]
  813.         mov     edx, [con_esc_attrs+(ecx-1)*4]
  814.         lea     edx, [edx*5]
  815.         lea     edx, [edx*2+eax]
  816.         mov     [con_esc_attrs+(ecx-1)*4], edx
  817.         pop     edx ecx eax
  818.         ret
  819. .questionmark:
  820.         push    ecx
  821.         mov     ecx, [con_esc_attr_n]
  822.         mov     dword[con_esc_attrs+(ecx-1)*4], 0xffffffff
  823.         pop     ecx
  824. .next_arg:
  825.         push    eax
  826.         mov     eax, [con_esc_attr_n]
  827.         inc     eax
  828.         cmp     al, 4
  829.         jbe     @f
  830.         dec     eax
  831. @@:
  832.         mov     [con_esc_attr_n], eax
  833.         and     [con_esc_attrs+(eax-1)*4], 0
  834.         pop     eax
  835.         ret
  836. .not_digit:
  837.         mov     [con_esc], 0
  838.         mov     [con_sci], 0    ; in any case, leave Esc mode
  839.         cmp     al, 'J'
  840.         jz      .clear
  841.         cmp     al, 'H'
  842.         jz      .setcursor
  843.         cmp     al, 'f'
  844.         jz      .setcursor
  845.         cmp     al, 'm'
  846.         jz      .set_attr
  847.         cmp     al, 'A'
  848.         jz      .cursor_up
  849.         cmp     al, 'B'
  850.         jz      .cursor_down
  851.         cmp     al, 'C'
  852.         jz      .cursor_right
  853.         cmp     al, 'D'
  854.         jz      .cursor_left
  855.         cmp     al, 'l'
  856.         je      .dec_rst
  857.         cmp     al, 'h'
  858.         je      .dec_set
  859.         ret     ; simply skip unknown sequences
  860.  
  861. .dec_rst:
  862.         mov     eax, [con_esc_attrs]
  863.         cmp     eax, 0xffffffff
  864.         jne     .no_dec_rst
  865.         mov     eax, [con_esc_attrs+4]
  866.         cmp     eax, 25
  867.         je      .hide_cursor
  868. .no_dec_rst:
  869.         ret
  870. .hide_cursor:
  871.         mov     [con.cursor_height], 0
  872.         ret
  873.  
  874. .dec_set:
  875.         mov     eax, [con_esc_attrs]
  876.         cmp     eax, 0xffffffff
  877.         jne     .no_dec_set
  878.         mov     eax, [con_esc_attrs+4]
  879.         cmp     eax, 25
  880.         je      .show_cursor
  881. .no_dec_set:
  882.         ret
  883.  
  884. .show_cursor:
  885.         mov     [con.cursor_height], (15*font_height+50)/100    ; default height
  886.         ret
  887. .clear:
  888.         mov     eax, [con_esc_attrs]
  889.         test    eax, eax
  890.         jz      .clear_till_end_of_screen       ; <esc>[0J (or <esc>[J)
  891.         dec     eax
  892.         jz      .clear_till_start_of_screen     ; <esc>[1J
  893.         dec     eax
  894.         je      .cls                            ; <esc>[2J
  895.         ret     ; unknown sequence
  896.  
  897. .clear_till_end_of_screen:
  898.         push    edi ecx
  899.         mov     ecx, [con.scr_width]
  900.         imul    ecx, [con.scr_height]
  901.  
  902.         mov     edi, [con.cur_y]
  903.         imul    edi, [con.scr_width]
  904.         add     edi, [con.cur_x]
  905.  
  906.         sub     ecx, edi
  907.         shl     edi, 1
  908.         add     edi, [con.data]
  909.         mov     ah, byte[con_flags]
  910.         mov     al, ' '
  911.         rep     stosw
  912.  
  913.         and     [con.cur_x], 0
  914.         and     [con.cur_y], 0
  915.         pop     ecx edi
  916.         ret
  917.  
  918. .clear_till_start_of_screen:
  919.         push    edi ecx
  920.         mov     ecx, [con.cur_y]
  921.         imul    ecx, [con.scr_width]
  922.         add     ecx, [con.cur_x]
  923.         mov     edi, [con.data]
  924.         mov     ah, byte[con_flags]
  925.         mov     al, ' '
  926.         rep     stosw
  927.         pop     ecx edi
  928.         ret
  929.  
  930. .cls:   ; clear screen completely
  931.         push    ecx
  932.         and     [con.cur_x], 0
  933.         and     [con.cur_y], 0
  934.         mov     edi, [con.data]
  935.         push    edi
  936.         mov     ecx, [con.scr_width]
  937.         imul    ecx, [con.scr_height]
  938.         mov     ax, 0720h
  939.         rep     stosw
  940.         pop     edi ecx
  941. .nosetcursor:
  942.         ret
  943. .setcursor:
  944.         cmp     [con_esc_attr_n], 2
  945.         je      @f
  946.         xor     eax, eax
  947.         mov     [con.cur_x], eax
  948.         mov     [con.cur_y], eax
  949.         jmp     .j_get_data
  950. @@:
  951.         mov     eax, [con_esc_attrs]
  952.         cmp     eax, [con.scr_width]
  953.         jae     @f
  954.         mov     [con.cur_x], eax
  955. @@:
  956.         mov     eax, [con_esc_attrs+4]
  957.         cmp     eax, [con.scr_height+4]
  958.         jae     @f
  959.         mov     [con.cur_y], eax
  960. .j_get_data:
  961.         jmp     con.get_data_ptr
  962. .cursor_up:
  963.         cmp     [con_esc_attr_n], 1
  964.         jnz     .nosetcursor
  965.         mov     eax, [con.cur_y]
  966.         sub     eax, [con_esc_attrs]
  967.         jnc     @f
  968.         xor     eax, eax
  969. @@:
  970.         mov     [con.cur_y], eax
  971.         jmp     .j_get_data
  972. .cursor_down:
  973.         cmp     [con_esc_attr_n], 1
  974.         jnz     .nosetcursor
  975.         mov     eax, [con.cur_y]
  976.         add     eax, [con_esc_attrs]
  977.         cmp     eax, [con.scr_height]
  978.         jb      @f
  979.         mov     eax, [con.scr_height]
  980.         dec     eax
  981. @@:
  982.         mov     [con.cur_y], eax
  983.         jmp     .j_get_data
  984. .cursor_right:
  985.         cmp     [con_esc_attr_n], 1
  986.         jnz     .nosetcursor
  987.         mov     eax, [con.cur_x]
  988.         add     eax, [con_esc_attrs]
  989.         cmp     eax, [con.scr_width]
  990.         jb      @f
  991.         mov     eax, [con.scr_width]
  992.         dec     eax
  993. @@:
  994.         mov     [con.cur_x], eax
  995.         jmp     .j_get_data
  996. .cursor_left:
  997.         cmp     [con_esc_attr_n], 1
  998.         jnz     .nosetcursor
  999.         mov     eax, [con.cur_x]
  1000.         sub     eax, [con_esc_attrs]
  1001.         jnc     @f
  1002.         xor     eax, eax
  1003. @@:
  1004.         mov     [con.cur_x], eax
  1005.         jmp     .j_get_data
  1006. .set_attr:
  1007.         push    eax ecx edx
  1008.         xor     ecx, ecx
  1009. .set_one_attr:
  1010.         mov     eax, [con_esc_attrs+ecx*4]
  1011.         cmp     al, 0
  1012.         jz      .attr_normal
  1013.         cmp     al, 1
  1014.         jz      .attr_bold
  1015.         cmp     al, 5
  1016.         jz      .attr_bgr_bold
  1017.         cmp     al, 7
  1018.         jz      .attr_reversed
  1019.  
  1020.         xor     edx, edx
  1021.         cmp     al, 30
  1022.         jz      .attr_color
  1023.         mov     dl, 4
  1024.         cmp     al, 31
  1025.         jz      .attr_color
  1026.         mov     dl, 2
  1027.         cmp     al, 32
  1028.         jz      .attr_color
  1029.         mov     dl, 6
  1030.         cmp     al, 33
  1031.         jz      .attr_color
  1032.         mov     dl, 1
  1033.         cmp     al, 34
  1034.         jz      .attr_color
  1035.         mov     dl, 5
  1036.         cmp     al, 35
  1037.         jz      .attr_color
  1038.         mov     dl, 3
  1039.         cmp     al, 36
  1040.         jz      .attr_color
  1041.         mov     dl, 7
  1042.         cmp     al, 37
  1043.         jz      .attr_color
  1044.  
  1045.         xor     edx, edx
  1046.         cmp     al, 40
  1047.         jz      .attr_bgr_color
  1048.         mov     dl, 0x40
  1049.         cmp     al, 41
  1050.         jz      .attr_bgr_color
  1051.         mov     dl, 0x20
  1052.         cmp     al, 42
  1053.         jz      .attr_bgr_color
  1054.         mov     dl, 0x60
  1055.         cmp     al, 43
  1056.         jz      .attr_bgr_color
  1057.         mov     dl, 0x10
  1058.         cmp     al, 44
  1059.         jz      .attr_bgr_color
  1060.         mov     dl, 0x50
  1061.         cmp     al, 45
  1062.         jz      .attr_bgr_color
  1063.         mov     dl, 0x30
  1064.         cmp     al, 46
  1065.         jz      .attr_bgr_color
  1066.         mov     dl, 0x70
  1067.         cmp     al, 47
  1068.         jz      .attr_bgr_color
  1069.  
  1070.         mov     dl, 0x08
  1071.         cmp     al, 90
  1072.         jz      .attr_color
  1073.         mov     dl, 4 + 8
  1074.         cmp     al, 91
  1075.         jz      .attr_color
  1076.         mov     dl, 2 + 8
  1077.         cmp     al, 92
  1078.         jz      .attr_color
  1079.         mov     dl, 6 + 8
  1080.         cmp     al, 93
  1081.         jz      .attr_color
  1082.         mov     dl, 1 + 8
  1083.         cmp     al, 94
  1084.         jz      .attr_color
  1085.         mov     dl, 5 + 8
  1086.         cmp     al, 95
  1087.         jz      .attr_color
  1088.         mov     dl, 3 + 8
  1089.         cmp     al, 96
  1090.         jz      .attr_color
  1091.         mov     dl, 7 + 8
  1092.         cmp     al, 97
  1093.         jz      .attr_color
  1094.  
  1095.         mov     dl, 0x80
  1096.         cmp     al, 100
  1097.         jz      .attr_bgr_color
  1098.         mov     dl, 0x80 + 0x40
  1099.         cmp     al, 101
  1100.         jz      .attr_bgr_color
  1101.         mov     dl, 0x80 + 0x20
  1102.         cmp     al, 102
  1103.         jz      .attr_bgr_color
  1104.         mov     dl, 0x80 + 0x60
  1105.         cmp     al, 103
  1106.         jz      .attr_bgr_color
  1107.         mov     dl, 0x80 + 0x10
  1108.         cmp     al, 104
  1109.         jz      .attr_bgr_color
  1110.         mov     dl, 0x80 + 0x50
  1111.         cmp     al, 105
  1112.         jz      .attr_bgr_color
  1113.         mov     dl, 0x80 + 0x30
  1114.         cmp     al, 106
  1115.         jz      .attr_bgr_color
  1116.         mov     dl, 0x80 + 0x70
  1117.         cmp     al, 107
  1118.         jnz     .attr_continue
  1119.  
  1120. .attr_bgr_color:
  1121.         mov     eax, [con_flags]
  1122.         and     al, 0x0F
  1123.         or      al, dl
  1124.         mov     [con_flags], eax
  1125.         jmp     .attr_continue
  1126. .attr_color:
  1127.         mov     eax, [con_flags]
  1128.         and     al, 0xF0
  1129.         or      al, dl
  1130.         mov     [con_flags], eax
  1131.         jmp     .attr_continue
  1132. .attr_normal:
  1133.         mov     byte [con_flags], 7
  1134.         jmp     .attr_continue
  1135. .attr_reversed:
  1136.         mov     byte [con_flags], 0x70
  1137.         jmp     .attr_continue
  1138. .attr_bold:
  1139.         or      byte [con_flags], 8
  1140.         jmp     .attr_continue
  1141. .attr_bgr_bold:
  1142.         or      byte [con_flags], 0x80
  1143. .attr_continue:
  1144.         inc     ecx
  1145.         cmp     ecx, [con_esc_attr_n]
  1146.         jb      .set_one_attr
  1147.         pop     edx ecx eax
  1148.         ret
  1149.  
  1150. con.newline:
  1151.         mov     eax, [con.cur_y]
  1152.         inc     eax
  1153.         mov     [con.cur_y], eax
  1154.         cmp     eax, [con.scr_height]
  1155.         jb      @f
  1156.         call    con.scr_scroll_up
  1157. @@:
  1158.         call    con.get_data_ptr
  1159.         ret
  1160.  
  1161. con.scr_scroll_up:
  1162.         pushad
  1163.         mov     edi, [con.data]
  1164.         mov     esi, edi
  1165.         add     esi, [con.scr_width]
  1166.         add     esi, [con.scr_width]
  1167.         dec     [con.cur_y]
  1168.         mov     ecx, [con.scr_height]
  1169.         dec     ecx
  1170.         imul    ecx, [con.scr_width]
  1171.         shr     ecx, 1
  1172.         rep     movsd
  1173.         adc     ecx, ecx
  1174.         rep     movsw
  1175.         mov     ax, 0x0720
  1176.         mov     ecx, [con.scr_width]
  1177.         rep     stosw
  1178.         popad
  1179.         ret
  1180.  
  1181. con.data2image:
  1182.         pushad
  1183.         mov     edi, [con.image]
  1184.         mov     esi, [con.data]
  1185.         mov     eax, [con.wnd_ypos]
  1186.         mul     [con.scr_width]
  1187.         add     eax, [con.wnd_xpos]
  1188.         lea     esi, [esi+eax*2]
  1189.         mov     ecx, [con.wnd_height]
  1190. .lh:
  1191.         push    ecx
  1192.         mov     ecx, [con.wnd_width]
  1193. .lw:
  1194.         push    ecx edi
  1195.         xor     eax, eax
  1196.         mov     al, [esi+1]
  1197.         push    eax
  1198.         and     al, 0xF
  1199.         mov     ebx, eax                ; 梥â ⥪áâ 
  1200.         pop     eax
  1201.         shr     al, 4
  1202.         mov     ebp, eax                ; 梥â ä®­ 
  1203.         sub     ebx, ebp
  1204.         lodsb
  1205.         inc     esi
  1206. if font_width > 8
  1207.         lea     edx, [eax+eax+font]
  1208. else
  1209.         lea     edx, [eax+font]
  1210. end if
  1211. .sh:
  1212.         mov     ecx, [edx]
  1213. repeat font_width
  1214.         shr     ecx, 1
  1215.         sbb     eax, eax
  1216.         and     eax, ebx
  1217.         add     eax, ebp
  1218.         mov     [edi+%-1], al
  1219. end repeat
  1220.         mov     eax, [con.wnd_width]
  1221. ;        imul    eax, font_width
  1222. ;        add     edi, eax
  1223. if font_width = 6
  1224.         lea     eax, [eax*2+eax]
  1225.         lea     edi, [edi+eax*2]
  1226. else if font_width = 7
  1227.         lea     edi, [edi+eax*8]
  1228.         sub     edi, eax
  1229. else if font_width = 8
  1230.         lea     edi, [edi+eax*8]
  1231. else if font_width = 9
  1232.         lea     edi, [edi+eax*8]
  1233.         add     edi, eax
  1234. else if font_width = 10
  1235.         lea     eax, [eax*4+eax]
  1236.         lea     edi, [edi+eax*2]
  1237. else
  1238. Unknown font_width value!
  1239. end if
  1240. if font_width > 8
  1241.         add     edx, 256*2
  1242.         cmp     edx, font+256*2*font_height
  1243. else
  1244.         add     edx, 256
  1245.         cmp     edx, font+256*font_height
  1246. end if
  1247.         jb      .sh
  1248.         pop     edi ecx
  1249.         add     edi, font_width
  1250.         sub     ecx, 1
  1251.         jnz     .lw
  1252.         mov     eax, [con.wnd_width]
  1253.         imul    eax, (font_height-1)*font_width
  1254.         add     edi, eax
  1255.         pop     ecx
  1256.         mov     eax, [con.scr_width]
  1257.         sub     eax, [con.wnd_width]
  1258.         lea     esi, [esi+eax*2]
  1259.         dec     ecx
  1260.         jnz     .lh
  1261.         mov     eax, [con.cur_y]
  1262.         sub     eax, [con.wnd_ypos]
  1263.         jb      .nocursor
  1264.         cmp     eax, [con.wnd_height]
  1265.         jae     .nocursor
  1266.         inc     eax
  1267.         mul     [con.wnd_width]
  1268.         imul    eax, font_height*font_width
  1269.         mov     edx, [con.cur_x]
  1270.         sub     edx, [con.wnd_xpos]
  1271.         jb      .nocursor
  1272.         cmp     edx, [con.wnd_width]
  1273.         jae     .nocursor
  1274.         inc     edx
  1275.         imul    edx, font_width
  1276.         add     eax, edx
  1277.         add     eax, [con.image]
  1278.         mov     edx, [con.wnd_width]
  1279.         imul    edx, font_width
  1280.         neg     edx
  1281.         mov     ecx, [con.cursor_height]
  1282.         jecxz   .nocursor
  1283. .cursor_loop:
  1284.         push    ecx
  1285.         mov     ecx, font_width
  1286.         add     eax, edx
  1287.         push    eax
  1288. @@:
  1289.         xor     byte [eax-1], 7
  1290.         dec     eax
  1291.         loop    @b
  1292.         pop     eax
  1293.         pop     ecx
  1294.         loop    .cursor_loop
  1295. .nocursor:
  1296.         popad
  1297.         ret
  1298.  
  1299. con_exit:
  1300.        
  1301.                 mov ah,[con.init_cmd]
  1302.                 test ah,ah
  1303.                 je .ret
  1304.  
  1305.         cmp     byte [esp+4], 0
  1306.         jz      .noexit
  1307.         mov     [con.thread_op], 1
  1308.         call    con.wake
  1309.                
  1310.         ret     4
  1311. .noexit:
  1312.         push    esi
  1313.         mov     esi, [con.title]
  1314.         mov     edx, con.finished_title
  1315.         mov     ecx, 255
  1316.         call    .strcpy
  1317.         mov     esi, con.aFinished
  1318.         call    .strcpy
  1319.         mov     byte [edx], 0
  1320.         pop     esi
  1321.         and     [con.cursor_height], 0
  1322.         push    con.finished_title
  1323.         call    con_set_title
  1324.         ret     4
  1325. .strcpy:
  1326.         jecxz   .ret
  1327. @@:
  1328.         lodsb
  1329.         test    al, al
  1330.         jz      .ret
  1331.         mov     [edx], al
  1332.         inc     edx
  1333.         loop    @b
  1334. .ret:
  1335.         ret
  1336.  
  1337. con_set_title:
  1338.         mov     eax, [esp+4]
  1339.         mov     [con.title], eax
  1340.         mov     [con.thread_op], 2
  1341.         call    con.wake
  1342.         ret     4
  1343.  
  1344. ; int __stdcall con_kbhit(void);
  1345. con_kbhit:
  1346.         test    byte [con_flags+1], 2
  1347.         jnz     @f
  1348.         mov     eax, [con.input_start]
  1349.         cmp     eax, [con.input_end]
  1350. @@:
  1351.         setnz   al
  1352.         movzx   eax, al
  1353.         ret
  1354.  
  1355. con.force_entered_char:
  1356.         cmp     [con.entered_char], -1
  1357.         jnz     .ret
  1358.         mov     [con.thread_op], 4
  1359.         call    con.wake
  1360.         test    byte [con_flags+1], 2
  1361.         jnz     .ret
  1362. ; wait for response
  1363.         push    ebx
  1364.         push    5
  1365.         pop     eax
  1366.         push    2
  1367.         pop     ebx
  1368. @@:
  1369.         int     0x40
  1370.         cmp     [con.entered_char], -1
  1371.         jz      @b
  1372.         pop     ebx
  1373. .ret:
  1374.         ret
  1375.  
  1376. ; int __stdcall con_getch(void);
  1377. con_getch:
  1378.                 call con_init_check
  1379.         call    con.force_entered_char
  1380.         test    byte [con_flags+1], 2
  1381.         jnz     con_getch_closed
  1382.         movzx   eax, byte [con.entered_char]
  1383.         sar     [con.entered_char], 8
  1384.         mov     byte [con.entered_char+1], 0xFF
  1385.         test    al, al
  1386.         jz      @f
  1387.         mov     byte [con.entered_char], 0xFF
  1388. @@:
  1389.         ret
  1390.  
  1391. con_getch_closed:
  1392.         xor     eax, eax
  1393.         ret
  1394.  
  1395. ; int __stdcall con_getch2(void);
  1396. con_getch2:
  1397.                 call con_init_check
  1398.         call    con.force_entered_char
  1399.         test    byte [con_flags+1], 2
  1400.         jnz     con_getch_closed
  1401.         mov     eax, 0xFFFF
  1402.         xchg    ax, [con.entered_char]
  1403.         ret
  1404.  
  1405. ; char* __stdcall con_gets(char* str, int n);
  1406. con_gets:
  1407.         pop     eax
  1408.         push    0
  1409.         push    eax
  1410. ; char* __stdcall con_gets2(con_gets2_callback callback, char* str, int n);
  1411. con_gets2:
  1412.                 call con_init_check
  1413.         mov     eax, [esp+8]            ; str
  1414.         pushad
  1415.         mov     esi, eax                ; str
  1416.         mov     ebx, [esp+20h+12]       ; n
  1417.         sub     ebx, 1
  1418.         jle     .ret
  1419.         mov     byte [esi], 0
  1420.         xor     ecx, ecx                ; ¤«¨­  㦥 ¢¢¥¤ñ­­®© áâப¨
  1421.         call    con.get_data_ptr
  1422. .loop:
  1423.         call    con_getch2
  1424.         test    al, al
  1425.         jz      .extended
  1426.         cmp     al, 8
  1427.         jz      .backspace
  1428.         cmp     al, 27
  1429.         jz      .esc
  1430.         cmp     al, 13
  1431.         jz      .enter
  1432.         cmp     al, 9
  1433.         jz      .tab
  1434.         inc     ecx
  1435.         mov     dl, al
  1436.         call    con.write_char_ex
  1437.         push    [con.cur_x]
  1438.         push    [con.cur_y]
  1439.         push    edi
  1440.         push    esi
  1441. @@:
  1442.         lodsb
  1443.         mov     [esi-1], dl
  1444.         mov     dl, al
  1445.         test    al, al
  1446.         jz      @f
  1447.         call    con.write_char_ex
  1448.         jmp     @b
  1449. @@:
  1450.         mov     [esi], dl
  1451.         pop     esi
  1452.         inc     esi
  1453.         pop     edi
  1454.         pop     [con.cur_y]
  1455.         pop     [con.cur_x]
  1456. .update_screen_and_loop:
  1457.         call    con.update_screen
  1458.         cmp     ecx, ebx
  1459.         jb      .loop
  1460. .ret_us:
  1461.         mov     edx, [con.cur_x]
  1462. @@:
  1463.         lodsb
  1464.         test    al, al
  1465.         jz      @f
  1466.         inc     edx
  1467.         cmp     edx, [con.scr_width]
  1468.         jb      @b
  1469.         xor     edx, edx
  1470.         call    con.newline
  1471.         jmp     @b
  1472. @@:
  1473.         mov     [con.cur_x], edx
  1474.         call    con.get_data_ptr
  1475.         call    con.update_screen
  1476.         jmp     .ret
  1477. .esc:
  1478.         mov     edx, [con.cur_x]
  1479. @@:
  1480.         lodsb
  1481.         test    al, al
  1482.         jz      @f
  1483.         inc     edx
  1484.         cmp     edx, [con.scr_width]
  1485.         jb      @b
  1486.         xor     edx, edx
  1487.         call    con.newline
  1488.         jmp     @b
  1489. @@:
  1490.         mov     [con.cur_x], edx
  1491.         call    con.get_data_ptr
  1492.         dec     esi
  1493.         xor     ecx, ecx
  1494. @@:
  1495.         mov     byte [esi], 0
  1496.         cmp     esi, [esp+20h+8]
  1497.         jbe     .update_screen_and_loop
  1498.         mov     al, 8
  1499.         call    con.write_special_char
  1500.         mov     al, ' '
  1501.         call    con.write_char
  1502.         mov     al, 8
  1503.         call    con.write_special_char
  1504.         dec     esi
  1505.         jmp     @b
  1506. .delete:
  1507.         cmp     byte [esi], 0
  1508.         jz      .loop
  1509.         lodsb
  1510.         call    con.write_char_ex
  1511. .backspace:
  1512.         cmp     esi, [esp+20h+8]
  1513.         jbe     .loop
  1514.         push    esi
  1515.         mov     edx, [con.cur_x]
  1516. @@:
  1517.         lodsb
  1518.         test    al, al
  1519.         jz      @f
  1520.         inc     edx
  1521.         cmp     edx, [con.scr_width]
  1522.         jb      @b
  1523.         xor     edx, edx
  1524.         call    con.newline
  1525.         jmp     @b
  1526. @@:
  1527.         mov     [con.cur_x], edx
  1528.         call    con.get_data_ptr
  1529.         dec     esi
  1530.         mov     al, 8
  1531.         call    con.write_special_char
  1532.         mov     al, ' '
  1533.         call    con.write_char
  1534.         mov     al, 8
  1535.         call    con.write_special_char
  1536.         mov     dl, 0
  1537. @@:
  1538.         cmp     esi, [esp]
  1539.         jbe     @f
  1540.         mov     al, 8
  1541.         call    con.write_special_char
  1542.         dec     esi
  1543.         xchg    dl, [esi]
  1544.         mov     al, dl
  1545.         call    con.write_char
  1546.         mov     al, 8
  1547.         call    con.write_special_char
  1548.         jmp     @b
  1549. @@:
  1550.         pop     esi
  1551.         dec     esi
  1552.         mov     [esi], dl
  1553.         dec     ecx
  1554.         jmp     .update_screen_and_loop
  1555. .enter:
  1556.         mov     edx, [con.cur_x]
  1557. @@:
  1558.         lodsb
  1559.         test    al, al
  1560.         jz      @f
  1561.         inc     edx
  1562.         cmp     edx, [con.scr_width]
  1563.         jb      @b
  1564.         xor     edx, edx
  1565.         call    con.newline
  1566.         jmp     @b
  1567. @@:
  1568.         mov     [con.cur_x], edx
  1569.         call    con.get_data_ptr
  1570.         mov     al, 10
  1571.         mov     [esi-1], al
  1572.         mov     byte [esi], 0
  1573.         call    con.write_special_char
  1574.         call    con.update_screen
  1575.         jmp     .ret
  1576. .tab:
  1577.         mov     al, 0
  1578.         mov     ah, 0xF
  1579. .extended:
  1580.         test    ah, ah
  1581.         jz      .closed
  1582.         xchg    al, ah
  1583.         cmp     al, 0x4B
  1584.         jz      .left
  1585.         cmp     al, 0x4D
  1586.         jz      .right
  1587.         cmp     al, 0x47
  1588.         jz      .home
  1589.         cmp     al, 0x4F
  1590.         jz      .end
  1591.         cmp     al, 0x53
  1592.         jz      .delete
  1593. ; give control to callback function
  1594.         cmp     dword [esp+20h+4], 0
  1595.         jz      .loop
  1596. ; remember length of text before and length of text after
  1597. ; and advance cursor to the end of line
  1598.         push    ecx
  1599.         push    eax
  1600.         lea     edx, [esi+1]
  1601. @@:
  1602.         lodsb
  1603.         test    al, al
  1604.         jz      @f
  1605.         call    con.write_char_ex
  1606.         jmp     @b
  1607. @@:
  1608.         sub     esi, edx
  1609.         pop     eax
  1610.         push    esi
  1611.         dec     edx
  1612.         sub     edx, [esp+28h+8]
  1613.         push    edx
  1614.         push    esp             ; ppos
  1615.         mov     ecx, [esp+30h+4]
  1616.         lea     edx, [esp+30h+12]
  1617.         push    edx             ; pn
  1618.         lea     edx, [esp+34h+8]
  1619.         push    edx             ; pstr
  1620.         push    eax             ; keycode
  1621.         call    ecx
  1622.         call    con.get_data_ptr
  1623.         dec     eax
  1624.         js      .callback_nochange
  1625.         jz      .callback_del
  1626.         dec     eax
  1627.         jz      .callback_output
  1628. ; callback returned 2 - exit
  1629.         add     esp, 12
  1630.         jmp     .ret
  1631. .callback_nochange:
  1632. ; callback returned 0 - string was not changed, only restore cursor position
  1633.         pop     esi
  1634.         pop     ecx
  1635.         test    ecx, ecx
  1636.         jz      .cncs
  1637. @@:
  1638.         mov     al, 8
  1639.         call    con.write_special_char
  1640.         loop    @b
  1641. .cncs:
  1642.         pop     ecx
  1643.         add     esi, [esp+20h+8]
  1644.         jmp     .callback_done
  1645. .callback_del:
  1646. ; callback returned 1 - string was changed, delete old string and output new
  1647.         mov     ecx, [esp+8]
  1648.         test    ecx, ecx
  1649.         jz      .cds
  1650. @@:
  1651.         mov     al, 8
  1652.         call    con.write_special_char
  1653.         mov     al, ' '
  1654.         call    con.write_char_ex
  1655.         mov     al, 8
  1656.         call    con.write_special_char
  1657.         loop    @b
  1658. .cds:
  1659. .callback_output:
  1660. ; callback returned 2 - string was changed, output new string
  1661.         pop     edx
  1662.         pop     esi
  1663.         pop     ecx
  1664.         mov     esi, [esp+20h+8]
  1665.         xor     ecx, ecx
  1666. @@:
  1667.         lodsb
  1668.         test    al, al
  1669.         jz      @f
  1670.         call    con.write_char_ex
  1671.         inc     ecx
  1672.         jmp     @b
  1673. @@:
  1674.         dec     esi
  1675.         push    ecx
  1676.         sub     ecx, edx
  1677.         jz      .cos
  1678. @@:
  1679.         mov     al, 8
  1680.         call    con.write_special_char
  1681.         dec     esi
  1682.         loop    @b
  1683. .cos:
  1684.         pop     ecx
  1685. .callback_done:
  1686.         call    con.update_screen
  1687.         mov     ebx, [esp+20h+12]
  1688.         dec     ebx
  1689.         cmp     ecx, ebx
  1690.         jae     .ret_us
  1691.         jmp     .loop
  1692. .left:
  1693.         cmp     esi, [esp+20h+8]
  1694.         jbe     .loop
  1695.         dec     esi
  1696.         mov     al, 8
  1697.         call    con.write_special_char
  1698.         jmp     .update_screen_and_loop
  1699. .right:
  1700.         cmp     byte [esi], 0
  1701.         jz      .loop
  1702.         lodsb
  1703.         call    con.write_char_ex
  1704.         jmp     .update_screen_and_loop
  1705. .home:
  1706.         cmp     esi, [esp+20h+8]
  1707.         jz      .update_screen_and_loop
  1708.         dec     esi
  1709.         mov     al, 8
  1710.         call    con.write_special_char
  1711.         jmp     .home
  1712. .end:
  1713.         lodsb
  1714.         test    al, al
  1715.         jz      @f
  1716.         call    con.write_char_ex
  1717.         jmp     .end
  1718. @@:
  1719.         dec     esi
  1720.         jmp     .update_screen_and_loop
  1721. .closed:
  1722.         and     dword [esp+1Ch], 0
  1723. .ret:
  1724.         popad
  1725.         ret     12
  1726.  
  1727. ; void __stdcall con_cls();
  1728. con_cls:
  1729.                 mov ah,[con.init_cmd]
  1730.                 test ah,ah
  1731.                 je cmd_init_no
  1732.                
  1733.         push    edi
  1734.         call    con.write_special_char.cls
  1735.         pop     edi
  1736.         call    con.update_screen
  1737.                
  1738.                 ret
  1739.                
  1740.                 cmd_init_no:
  1741.                
  1742.                 push con.title_init_console
  1743.                 push -1
  1744.                 push -1
  1745.                 push -1
  1746.                 push -1
  1747.                
  1748.                 call con_init
  1749.                
  1750.         ret
  1751.  
  1752. ; void __stdcall con_get_cursor_pos(int* px, int* py);
  1753. con_get_cursor_pos:
  1754.         push    eax ecx
  1755.         mov     eax, [esp+12]
  1756.         mov     ecx, [con.cur_x]
  1757.         mov     [eax], ecx
  1758.         mov     eax, [esp+16]
  1759.         mov     ecx, [con.cur_y]
  1760.         mov     [eax], ecx
  1761.         pop     ecx eax
  1762.         ret     8
  1763.  
  1764. ; void __stdcall con_set_cursor_pos(int px, int py);
  1765. con_set_cursor_pos:
  1766.         push    eax
  1767.         mov     eax, [esp+8]
  1768.         cmp     eax, [con.scr_width]
  1769.         jae     @f
  1770.         mov     [con.cur_x], eax
  1771. @@:
  1772.         mov     eax, [esp+12]
  1773.         cmp     eax, [con.scr_height]
  1774.         jae     @f
  1775.         mov     [con.cur_y], eax
  1776. @@:
  1777.         pop     eax
  1778.         call    con.update_screen
  1779.         ret     8
  1780.  
  1781. con.update_screen:
  1782.         push    eax
  1783.         mov     eax, [con.cur_y]
  1784.         sub     eax, [con.wnd_ypos]
  1785.         jb      .up
  1786.         cmp     eax, [con.wnd_height]
  1787.         jb      .done
  1788.         mov     eax, [con.cur_y]
  1789.         sub     eax, [con.wnd_height]
  1790.         inc     eax
  1791.         jmp     .set
  1792. .up:
  1793.         mov     eax, [con.cur_y]
  1794. .set:
  1795.         mov     [con.wnd_ypos], eax
  1796. .done:
  1797.         pop     eax
  1798.         mov     [con.thread_op], 3
  1799.  
  1800. con.wake:
  1801.         pushad
  1802.         mov     al, [con.thread_op]
  1803.         cmp     al, byte [con.ipc_buf+0x10]
  1804.         jz      .ret
  1805. @@:
  1806.         push    60
  1807.         pop     eax
  1808.         push    2
  1809.         pop     ebx
  1810.         mov     ecx, [con.console_tid]
  1811.         jecxz   .ret
  1812.         mov     edx, con.thread_op
  1813.         push    1
  1814.         pop     esi
  1815.         int     0x40
  1816.         test    eax, eax
  1817.         jz      @f
  1818.         push    5
  1819.         pop     eax
  1820.         mov     bl, 1
  1821.         int     0x40
  1822.         jmp     @b
  1823. @@:
  1824. .ret:
  1825.         popad
  1826.         ret
  1827.  
  1828. ; ®â®ª ®ª­  ª®­á®«¨. Ž¡à ¡ â뢠¥â ¢¢®¤ ¨ ¢ë¢®¤.
  1829. con.thread:
  1830.         or      [con.vscroll_pt], -1
  1831. ; ®â®ª ॠ£¨àã¥â ­  IPC, ª®â®à®¥ ¨á¯®«ì§ã¥âáï ⮫쪮 ¤«ï ⮣®, çâ®¡ë ¥£® ¬®¦­® ¡ë«® "à §¡ã¤¨âì"
  1832.         push    40
  1833.         pop     eax
  1834.         push    0x67
  1835.         pop     ebx
  1836.         int     0x40
  1837.         mov     al, 60
  1838.         mov     bl, 1
  1839.         mov     ecx, con.ipc_buf
  1840.         mov     byte [ecx+4], 8
  1841.         push    0x11
  1842.         pop     edx
  1843.         int     0x40
  1844.         mov     al, 66
  1845.         mov     bl, 1
  1846.         mov     ecx, ebx
  1847.         int     0x40
  1848. con.redraw:
  1849.         call    con.draw_window
  1850. con.msg_loop:
  1851.         cmp     dword [con.bUpPressed], 0
  1852.         jnz     .wait_timeout
  1853.         push    10
  1854.         pop     eax
  1855.         jmp     @f
  1856. .wait_timeout:
  1857.         push    23
  1858.         pop     eax
  1859.         push    5
  1860.         pop     ebx
  1861. @@:
  1862.         int     0x40
  1863.         dec     eax
  1864.         jz      con.redraw
  1865.         dec     eax
  1866.         jz      con.key
  1867.         dec     eax
  1868.         jz      con.button
  1869.         cmp     al, 4
  1870.         jz      con.ipc
  1871.         jmp     con.mouse
  1872. con.button:
  1873. ; we have only one button, close
  1874. con.thread_exit:
  1875.         or      byte [con_flags+1], 2
  1876.         and     [con.console_tid], 0
  1877.         and     [con.entered_char], 0
  1878.         or      eax, -1
  1879.         int     0x40
  1880. con.key:
  1881.         mov     al, 2
  1882.         int     0x40
  1883.         and     eax, 0xffff ; supress scancodes
  1884. ; ah = scancode
  1885.         cmp     ah, 0xE0
  1886.         jnz     @f
  1887.         mov     [con.bWasE0], 1
  1888.         jmp     con.msg_loop
  1889. @@:
  1890.         shr     eax, 8
  1891.         xchg    ah, [con.bWasE0]
  1892.         test    al, al
  1893.         jle     con.msg_loop
  1894.         cmp     al, 0x1D
  1895.         jz      con.msg_loop
  1896.         cmp     al, 0x2A
  1897.         jz      con.msg_loop
  1898.         cmp     al, 0x36
  1899.         jz      con.msg_loop
  1900.         cmp     al, 0x38
  1901.         jz      con.msg_loop
  1902.         cmp     al, 0x3A
  1903.         jz      con.msg_loop
  1904.         cmp     al, 0x45
  1905.         jz      con.msg_loop
  1906.         cmp     al, 0x46
  1907.         jz      con.msg_loop
  1908.         mov     edx, eax
  1909.         cmp     dl, 0x4e
  1910.         je      .numpad
  1911.         cmp     dl, 0x4a
  1912.         je      .numpad
  1913.         push    66
  1914.         pop     eax
  1915.         push    3
  1916.         pop     ebx
  1917.         int     0x40    ; eax = control key state
  1918.         test    dh, dh
  1919.         jnz     .extended
  1920.         test    al, 0x80        ; numlock
  1921.         jnz     .numlock
  1922.         bt      [scan_has_ascii], edx
  1923.         jnc     .extended
  1924.         test    al, 0x30        ; alt
  1925.         jnz     .extended
  1926.         test    al, 0x80        ; numlock
  1927.         jz      .no_numlock
  1928.   .numlock:
  1929.         cmp     dl, 71
  1930.         jb      .no_numlock
  1931.         cmp     dl, 83
  1932.         ja      .no_numlock
  1933.   .numpad:
  1934.         mov     dh, [con.extended_numlock+edx-71]
  1935.         xchg    dl, dh
  1936.         jmp     .gotcode
  1937.   .no_numlock:
  1938. ; key has ASCII code
  1939.         push    eax edx
  1940.         push    2
  1941.         pop     ecx
  1942.         test    al, 3
  1943.         jnz     @f
  1944.         dec     ecx
  1945. @@:
  1946.         push    26
  1947.         pop     eax
  1948.         mov     bl, 2
  1949.         mov     edx, con.kbd_layout
  1950.         int     0x40
  1951.         pop     edx eax
  1952.         mov     dh, [con.kbd_layout+edx]
  1953.         test    al, 0xC
  1954.         jz      @f
  1955.         sub     dh, 0x60
  1956.         jmp     @f
  1957. .extended:
  1958.         mov     dh, 0   ; no ASCII code
  1959. @@:
  1960. ; dh contains ASCII-code; now convert scancode to extended key code
  1961.         mov     ecx, con.extended_alt
  1962.         test    al, 0x30
  1963.         jnz     .xlat
  1964.  
  1965.         mov     ecx, con.extended_shift
  1966.         test    al, 3
  1967.         jnz     .xlat
  1968.  
  1969.         mov     ecx, con.extended_ctrl
  1970.         test    al, 0xC
  1971.         jnz     .xlat
  1972.  
  1973.         cmp     dl, 28
  1974.         jne     @f
  1975.         shl     dx, 8
  1976.         mov     dl, 13
  1977.         jmp     .gotcode
  1978. @@:
  1979.         cmp     dl, 53
  1980.         jne     @f
  1981.         shl     dx, 8
  1982.         mov     dl, '/'
  1983.         jmp     .gotcode
  1984. @@:
  1985.         cmp     dl, 55
  1986.         jne     @f
  1987.         shl     dx, 8
  1988.         mov     dl, '*'
  1989.         jmp     .gotcode
  1990. @@:
  1991.         xchg    dl, dh
  1992.         cmp     dh, 0x57
  1993.         jz      @f
  1994.         cmp     dh, 0x58
  1995.         jnz     .gotcode
  1996. @@:
  1997.         add     dh, 0x85-0x57
  1998.         jmp     .gotcode
  1999. .xlat:
  2000.         movzx   eax, dl
  2001.         mov     dl, dh
  2002.         mov     dh, [eax+ecx]
  2003. .gotcode:
  2004.         test    dh, dh
  2005.         jz      con.msg_loop
  2006.         cmp     dh, 0x94
  2007.         jnz     @f
  2008.         mov     dl, 0
  2009. @@:
  2010. ; dx contains full keycode
  2011.         cmp     [con.bGetchRequested], 0
  2012.         jz      @f
  2013.         mov     [con.entered_char], dx
  2014.         jmp     con.msg_loop
  2015. @@:
  2016.         mov     eax, [con.input_end]
  2017.         mov     ecx, eax
  2018.         add     eax, 2
  2019.         cmp     eax, con.input_buffer_end
  2020.         jnz     @f
  2021.         mov     eax, con.input_buffer
  2022. @@:
  2023.         cmp     eax, [con.input_start]
  2024.         jnz     @f
  2025. ; buffer overflow, make beep and continue
  2026.         push    55
  2027.         pop     eax
  2028.         mov     ebx, eax
  2029.         mov     esi, con.beep
  2030.         int     0x40
  2031.         jmp     con.msg_loop
  2032. @@:
  2033.         mov     [ecx], dx
  2034.         mov     [con.input_end], eax
  2035.         jmp     con.msg_loop
  2036. con.ipc:
  2037.         movzx   eax, byte [con.ipc_buf+0x10]
  2038.         mov     byte [con.ipc_buf+4], 8
  2039.         mov     byte [con.ipc_buf+0x10], 0
  2040.         dec     eax
  2041.         jz      con.thread_exit
  2042.         dec     eax
  2043.         jz      con.set_title
  2044.         dec     eax
  2045.         jz      con.redraw_image
  2046.         dec     eax
  2047.         jz      con.getch
  2048.         jmp     con.msg_loop
  2049. con.set_title:
  2050.         push    71
  2051.         pop     eax
  2052.         push    1
  2053.         pop     ebx
  2054.         mov     ecx, [con.title]
  2055.         int     0x40
  2056.         jmp     con.msg_loop
  2057. con.redraw_image:
  2058.         call    con.data2image
  2059.         call    con.draw_image
  2060.         jmp     con.msg_loop
  2061. con.getch:
  2062.         mov     eax, [con.input_start]
  2063.         cmp     eax, [con.input_end]
  2064.         jz      .noinput
  2065.         mov     ecx, [eax]
  2066.         mov     [con.entered_char], cx
  2067.         inc     eax
  2068.         inc     eax
  2069.         cmp     eax, con.input_buffer_end
  2070.         jnz     @f
  2071.         mov     eax, con.input_buffer
  2072. @@:
  2073.         mov     [con.input_start], eax
  2074.         jmp     con.msg_loop
  2075. .noinput:
  2076.         mov     [con.bGetchRequested], 1
  2077.         jmp     con.msg_loop
  2078. con.mouse:
  2079.         push    37
  2080.         pop     eax
  2081.         push    7
  2082.         pop     ebx
  2083.         int     0x40
  2084.         test    eax, eax
  2085.         jz      .no_scrollmouse
  2086.         cwde
  2087.         add     eax, [con.wnd_ypos]
  2088.         jg      @f
  2089.         xor     eax, eax
  2090. @@:
  2091.         mov     ebx, [con.scr_height]
  2092.         sub     ebx, [con.wnd_height]
  2093.         cmp     eax, ebx
  2094.         jb      @f
  2095.         mov     eax, ebx
  2096. @@:
  2097.         mov     [con.wnd_ypos], eax
  2098.         jmp     con.redraw_image
  2099. .no_scrollmouse:
  2100.         xor     eax, eax
  2101.         xchg    eax, dword [con.bUpPressed]
  2102.         mov     dword [con.bUpPressed_saved], eax
  2103.         push    37
  2104.         pop     eax
  2105.         push    2
  2106.         pop     ebx
  2107.         int     0x40
  2108.         test    al, 1
  2109.         jnz     @f
  2110.         cmp     [con.vscroll_pt], -1
  2111.         jz      .redraw_if_needed
  2112.         or      [con.vscroll_pt], -1
  2113. .redraw_if_needed:
  2114.         cmp     dword [con.bUpPressed_saved], 0
  2115.         jnz     con.redraw_image
  2116.         jmp     con.msg_loop
  2117. @@:
  2118.         mov     al, 37
  2119.         dec     ebx
  2120.         int     0x40
  2121.         movsx   ebx, ax
  2122.         sar     eax, 16
  2123.         cmp     [con.vscroll_pt], -1
  2124.         jnz     .vscrolling
  2125.         test    ebx, ebx
  2126.         js      .redraw_if_needed
  2127.         sub     ax, [con.data_width]
  2128.         jb      .redraw_if_needed
  2129.         cmp     eax, con.vscroll_width
  2130.         jae     .redraw_if_needed
  2131.         cmp     ebx, con.vscroll_btn_height
  2132.         jb      .up
  2133.         sub     bx, [con.data_height]
  2134.         jae     .redraw_if_needed
  2135.         cmp     bx, -con.vscroll_btn_height
  2136.         jge     .down
  2137.         add     bx, [con.data_height]
  2138.         sub     bx, word [con.vscrollbar_pos]
  2139.         jl      .vscroll_up
  2140.         cmp     bx, word [con.vscrollbar_size]
  2141.         jl      .vscroll
  2142. .vscroll_down:
  2143.         cmp     [con.bScrollingDown_saved], 0
  2144.         jz      .vscroll_down_first
  2145.         cmp     [con.bScrollingDown_saved], 1
  2146.         jz      .vscroll_down_wasfirst
  2147.         mov     [con.bScrollingDown], 2
  2148. .vscroll_down_do:
  2149.         mov     eax, [con.wnd_ypos]
  2150.         add     eax, [con.wnd_height]
  2151.         dec     eax
  2152.         mov     ebx, [con.scr_height]
  2153.         sub     ebx, [con.wnd_height]
  2154.         cmp     eax, ebx
  2155.         jb      @f
  2156.         mov     eax, ebx
  2157. @@:
  2158.         mov     [con.wnd_ypos], eax
  2159.         jmp     con.redraw_image
  2160. .vscroll_down_first:
  2161.         push    26
  2162.         pop     eax
  2163.         push    9
  2164.         pop     ebx
  2165.         int     0x40
  2166.         mov     [con.scroll_down_first_time], eax
  2167.         mov     [con.bScrollingDown], 1
  2168.         jmp     .vscroll_down_do
  2169. .vscroll_down_wasfirst:
  2170.         push    26
  2171.         pop     eax
  2172.         push    9
  2173.         pop     ebx
  2174.         int     0x40
  2175.         sub     eax, [con.scroll_down_first_time]
  2176.         cmp     eax, 25
  2177.         jb      @f
  2178.         mov     [con.bScrollingDown], 2
  2179.         jmp     .vscroll_down_do
  2180. @@:
  2181.         mov     [con.bScrollingDown], 1
  2182.         jmp     con.msg_loop
  2183. .vscroll_up:
  2184.         cmp     [con.bScrollingUp_saved], 0
  2185.         jz      .vscroll_up_first
  2186.         cmp     [con.bScrollingUp_saved], 1
  2187.         jz      .vscroll_up_wasfirst
  2188.         mov     [con.bScrollingUp], 2
  2189. .vscroll_up_do:
  2190.         mov     eax, [con.wnd_ypos]
  2191.         inc     eax
  2192.         sub     eax, [con.wnd_height]
  2193.         jns     @f
  2194.         xor     eax, eax
  2195. @@:
  2196.         mov     [con.wnd_ypos], eax
  2197.         jmp     con.redraw_image
  2198. .vscroll_up_first:
  2199.         push    26
  2200.         pop     eax
  2201.         push    9
  2202.         pop     ebx
  2203.         int     0x40
  2204.         mov     [con.scroll_up_first_time], eax
  2205.         mov     [con.bScrollingUp], 1
  2206.         jmp     .vscroll_up_do
  2207. .vscroll_up_wasfirst:
  2208.         push    26
  2209.         pop     eax
  2210.         push    9
  2211.         pop     ebx
  2212.         int     0x40
  2213.         sub     eax, [con.scroll_up_first_time]
  2214.         cmp     eax, 25
  2215.         jb      @f
  2216.         mov     [con.bScrollingUp], 2
  2217.         jmp     .vscroll_up_do
  2218. @@:
  2219.         mov     [con.bScrollingUp], 1
  2220.         jmp     con.msg_loop
  2221. .up:
  2222.         cmp     [con.bUpPressed_saved], 0
  2223.         jz      .up_first
  2224.         cmp     [con.bUpPressed_saved], 1
  2225.         jz      .up_wasfirst
  2226.         mov     [con.bUpPressed], 2
  2227. .up_do:
  2228.         mov     eax, [con.wnd_ypos]
  2229.         dec     eax
  2230.         js      @f
  2231.         mov     [con.wnd_ypos], eax
  2232. @@:
  2233.         jmp     con.redraw_image
  2234. .up_first:
  2235.         push    26
  2236.         pop     eax
  2237.         push    9
  2238.         pop     ebx
  2239.         int     0x40
  2240.         mov     [con.up_first_time], eax
  2241.         mov     [con.bUpPressed], 1
  2242.         jmp     .up_do
  2243. .up_wasfirst:
  2244.         push    26
  2245.         pop     eax
  2246.         push    9
  2247.         pop     ebx
  2248.         int     0x40
  2249.         sub     eax, [con.up_first_time]
  2250.         cmp     eax, 25
  2251.         jb      @f
  2252.         mov     [con.bUpPressed], 2
  2253.         jmp     .up_do
  2254. @@:
  2255.         mov     [con.bUpPressed], 1
  2256.         jmp     con.msg_loop
  2257. .down:
  2258.         cmp     [con.bDownPressed_saved], 0
  2259.         jz      .down_first
  2260.         cmp     [con.bDownPressed_saved], 1
  2261.         jz      .down_wasfirst
  2262.         mov     [con.bDownPressed], 2
  2263. .down_do:
  2264.         mov     eax, [con.scr_height]
  2265.         sub     eax, [con.wnd_height]
  2266.         jbe     con.redraw_image
  2267.         cmp     [con.wnd_ypos], eax
  2268.         jae     con.redraw_image
  2269.         inc     [con.wnd_ypos]
  2270.         jmp     con.redraw_image
  2271. .down_first:
  2272.         push    26
  2273.         pop     eax
  2274.         push    9
  2275.         pop     ebx
  2276.         int     0x40
  2277.         mov     [con.down_first_time], eax
  2278.         mov     [con.bDownPressed], 1
  2279.         jmp     .down_do
  2280. .down_wasfirst:
  2281.         push    26
  2282.         pop     eax
  2283.         push    9
  2284.         pop     ebx
  2285.         int     0x40
  2286.         sub     eax, [con.down_first_time]
  2287.         cmp     eax, 25
  2288.         jb      @f
  2289.         mov     [con.bDownPressed], 2
  2290.         jmp     .down_do
  2291. @@:
  2292.         mov     [con.bDownPressed], 1
  2293.         jmp     con.msg_loop
  2294. .vscroll:
  2295.         mov     [con.vscroll_pt], ebx
  2296.         call    con.draw_image
  2297.         jmp     con.msg_loop
  2298. .vscrolling:
  2299.         sub     ebx, [con.vscroll_pt]
  2300.         sub     ebx, con.vscroll_btn_height
  2301.         jge     @f
  2302.         xor     ebx, ebx
  2303. @@:
  2304.         movzx   eax, [con.data_height]
  2305.         sub     eax, 2*con.vscroll_btn_height
  2306.         sub     eax, [con.vscrollbar_size]
  2307.         cmp     ebx, eax
  2308.         jb      @f
  2309.         lea     ebx, [eax-1]
  2310. @@:
  2311.         xchg    eax, ebx
  2312.         mov     edx, [con.scr_height]
  2313.         sub     edx, [con.wnd_height]
  2314.         inc     edx
  2315.         mul     edx
  2316.         div     ebx
  2317.         cmp     [con.wnd_ypos], eax
  2318.         jz      con.msg_loop
  2319.         mov     [con.wnd_ypos], eax
  2320.         jmp     con.redraw_image
  2321.  
  2322. con.draw_window:
  2323.         push    12
  2324.         pop     eax
  2325.         xor     ebx, ebx
  2326.         inc     ebx
  2327.         int     0x40
  2328.         mov     al, 48
  2329.         mov     bl, 4
  2330.         int     0x40
  2331.         mov     ebx, [con.def_wnd_x-2]
  2332.         mov     bx, word [con.wnd_width]
  2333.         imul    bx, font_width
  2334.         add     bx, 5+5-1
  2335.         mov     ecx, [con.def_wnd_y-2]
  2336.         mov     cx, word [con.wnd_height]
  2337.         imul    cx, font_height
  2338.         lea     ecx, [ecx+eax+5-1]
  2339.         mov     edx, 0x74000000
  2340.         mov     edi, [con.title]
  2341. ; place for scrollbar
  2342.         mov     eax, [con.wnd_height]
  2343.         cmp     eax, [con.scr_height]
  2344.         jae     @f
  2345.         add     ebx, con.vscroll_width
  2346. @@:
  2347.         xor     eax, eax
  2348.         int     0x40
  2349.         ;Leency{
  2350.         mov     eax,9
  2351.         mov     ebx,process_info_buffer
  2352.         mov     ecx,-1
  2353.         int     0x40
  2354.         mov     eax,[ebx+70]
  2355.         mov     [window_status],eax
  2356.                 test    [window_status],100b   ; window is rolled up
  2357.         jnz     .exit
  2358.         test    [window_status],10b    ; window is minimized to panel
  2359.         jnz     .exit
  2360.         ;}Leency - I'm in diamond code...
  2361.         call    con.draw_image
  2362.  
  2363. .exit:
  2364.         push    12
  2365.         pop     eax
  2366.         push    2
  2367.         pop     ebx
  2368.         int     0x40
  2369.                
  2370.         ret
  2371.  
  2372. con.draw_image:
  2373.         xor     edx, edx
  2374.         mov     ecx, [con.wnd_width]
  2375.         imul    ecx, font_width
  2376.         mov     [con.data_width], cx
  2377.         shl     ecx, 16
  2378.         mov     cx, word [con.wnd_height]
  2379.         imul    cx, font_height
  2380.         mov     [con.data_height], cx
  2381.         mov     ebx, [con.image]
  2382.         push    65
  2383.         pop     eax
  2384.         xor     ebp, ebp
  2385.         mov     edi, con.colors
  2386.         push    8
  2387.         pop     esi
  2388.         int     0x40
  2389.         mov     al, 7
  2390.         mov     edx, [con.wnd_height]
  2391.         cmp     edx, [con.scr_height]
  2392.         jae     .skip_vscroll
  2393.         push    ecx
  2394.         mov     edx, ecx
  2395.         xor     dx, dx
  2396.         mov     ebx, con.vscroll_btn3
  2397.         cmp     [con.bUpPressed], 0
  2398.         jnz     @f
  2399.         mov     ebx, con.vscroll_btn1
  2400. @@:
  2401.         mov     ecx, con.vscroll_width*65536 + con.vscroll_btn_height
  2402.         int     0x40
  2403.         pop     edx
  2404.         sub     dx, con.vscroll_btn_height
  2405.         mov     ebx, con.vscroll_btn4
  2406.         cmp     [con.bDownPressed], 0
  2407.         jnz     @f
  2408.         mov     ebx, con.vscroll_btn2
  2409. @@:
  2410.         int     0x40
  2411.         push    edx
  2412. ; ‚ëç¨á«ï¥¬ ¢ëá®âã ¡¥£ã­ª 
  2413.         mov     ax, dx
  2414.         sub     eax, con.vscroll_btn_height
  2415.         mov     ecx, eax
  2416.         mul     [con.wnd_height]
  2417.         div     [con.scr_height]
  2418.         cmp     eax, 5
  2419.         jae     @f
  2420.         mov     al, 5
  2421. @@:
  2422. ; eax = ¢ëá®â  ¡¥£ã­ª . ‚ëç¨á«ï¥¬ ¯®«®¦¥­¨¥ ¡¥£ã­ª 
  2423.         mov     [con.vscrollbar_size], eax
  2424.         xchg    eax, ecx
  2425.         sub     eax, ecx
  2426.         mul     [con.wnd_ypos]
  2427.         mov     ebx, [con.scr_height]
  2428.         sub     ebx, [con.wnd_height]
  2429.         div     ebx
  2430.         pop     edx
  2431.         push    edx
  2432. ; ecx = ¢ëá®â  ¡¥£ã­ª , eax = ¯®«®¦¥­¨¥
  2433.         add     eax, con.vscroll_btn_height
  2434.         mov     [con.vscrollbar_pos], eax
  2435.         mov     ebx, con.vscroll_bgr2
  2436.         cmp     [con.bScrollingUp], 0
  2437.         jnz     @f
  2438.         mov     ebx, con.vscroll_bgr1
  2439. @@:
  2440.         mov     ecx, con.vscroll_width*65536 + con.vscroll_bgr_height
  2441.         push    eax
  2442.         push    7
  2443.         pop     eax
  2444.         mov     dx, con.vscroll_btn_height
  2445.         call    .vpattern
  2446.         mov     dx, word [con.vscrollbar_pos]
  2447.         add     dx, word [con.vscrollbar_size]
  2448.         mov     cx, con.vscroll_bgr_height
  2449.         mov     ebx, con.vscroll_bgr2
  2450.         cmp     [con.bScrollingDown], 0
  2451.         jnz     @f
  2452.         mov     ebx, con.vscroll_bgr1
  2453. @@:
  2454.         call    .vpattern
  2455.         mov     ecx, [con.vscrollbar_pos]
  2456.         mov     dx, cx
  2457.         add     ecx, [con.vscrollbar_size]
  2458.         sub     ecx, con.vscroll_bar_height3
  2459.         push    ecx
  2460.         mov     ebx, con.vscroll_bar1
  2461.         mov     ecx, con.vscroll_width*65536 + con.vscroll_bar_height1
  2462.         int     0x40
  2463.         add     dx, cx
  2464.         mov     cx, con.vscroll_bar_height2
  2465.         mov     ebx, con.vscroll_bar2
  2466.         call    .vpattern
  2467.         mov     ebx, con.vscroll_bar3
  2468.         mov     cx, con.vscroll_bar_height3
  2469.         int     0x40
  2470. .skip_vscroll:
  2471.         ret
  2472.  
  2473. .vpattern:
  2474.         push    edx
  2475.         add     dx, cx
  2476.         cmp     dx, [esp+8]
  2477.         pop     edx
  2478.         jbe     @f
  2479.         mov     cx, [esp+4]
  2480.         sub     cx, dx
  2481.         jz      .ret
  2482. @@:
  2483.         int     0x40
  2484.         add     dx, cx
  2485.         cmp     dx, [esp+4]
  2486.         jb      .vpattern
  2487. .ret:
  2488.         ret     4
  2489.  
  2490. align 4
  2491. con.colors      dd      0x000000, 0x000080, 0x008000, 0x008080
  2492.                 dd      0x800000, 0x800080, 0x808000, 0xC0C0C0
  2493.                 dd      0x808080, 0x0000FF, 0x00FF00, 0x00FFFF
  2494.                 dd      0xFF0000, 0xFF00FF, 0xFFFF00, 0xFFFFFF
  2495.  
  2496. scan_has_ascii:
  2497.         dd      11011111111111111111111111111110b
  2498.         dd      00000010001111111111101111111111b
  2499.         dd      00000000000000000000000000000000b
  2500.         dd      0
  2501.  
  2502. con.extended_alt:
  2503.         db      00h,01h,78h,79h,7Ah,7Bh,7Ch,7Dh,7Eh,7Fh,80h,81h,82h,83h,0Eh,0A5h
  2504.         db      10h,11h,12h,13h,14h,15h,16h,17h,18h,19h,1Ah,1Bh,1Ch,00h,1Eh,1Fh
  2505.         db      20h,21h,22h,23h,24h,25h,26h,27h,28h,29h,00h,2Bh,2Ch,2Dh,2Eh,2Fh
  2506.         db      30h,31h,32h,33h,34h,35h,00h,37h,00h,39h,00h,68h,69h,6Ah,6Bh,6Ch
  2507.         db      6Dh,6Eh,6Fh,70h,71h,00h,00h,97h,98h,99h,4Ah,9Bh,9Ch,9Dh,4Eh,9Fh
  2508.         db      0A0h,0A1h,0A2h,0A3h,00h,00h,00h,8Bh,8Ch,00h,00h,00h,00h,00h,00h,00h
  2509.         times 20h db 0
  2510. con.extended_ctrl:
  2511.         times 0Fh db %-1
  2512.         db      0x94
  2513.         times 2Bh db %-1
  2514.         db      5Eh,5Fh,60h,61h,62h,63h,64h,65h,66h,67h,00h,00h
  2515.         db      77h,8Dh,84h,8Eh,73h,8Fh,74h,90h,75h,91h,76h,92h,93h,00h,00h,00h,89h,8Ah
  2516.         times 0x80-0x59 db 0
  2517. con.extended_shift:
  2518.         times 3Bh db %-1
  2519.         db      54h,55h,56h,57h,58h,59h,5Ah,5Bh,5Ch,5Dh,00h,00h
  2520.         db      47h,48h,49h,4Ah,4Bh,4Ch,4Dh,4Eh,4Fh,50h,51h,52h,53h,00h,00h,00h,87h,88h
  2521.         times 0x80-0x59 db 0
  2522. con.extended_numlock:
  2523.         db      '7', '8', '9', '-'
  2524.         db      '4', '5', '6', '+'
  2525.         db      '1', '2', '3'
  2526.         db      '0', '.'
  2527.  
  2528. ; ‚ ⥪ã饩 ॠ«¨§ æ¨¨ §­ ç¥­¨ï ¯® 㬮«ç ­¨î â ª®¢ë.
  2529. ; ‚ ¡ã¤ã饬 ®­¨, ¢®§¬®¦­®, ¡ã¤ãâ áç¨â뢠âìáï ª ª ¯ à ¬¥âàë ¨§ ini-ä ©«  console.ini.
  2530. con.def_wnd_width   dd    80
  2531. con.def_wnd_height  dd    25
  2532. con.def_scr_width   dd    80
  2533. con.def_scr_height  dd    300
  2534. con.def_wnd_x       dd    200
  2535. con.def_wnd_y       dd    50
  2536.  
  2537. con.title_init_console db "Console",0
  2538.  
  2539. align 4
  2540. data export
  2541. export 'console.dll', \
  2542.         version, 'version', \
  2543.         con_init, 'con_init', \
  2544.         con_write_asciiz, 'con_write_asciiz', \
  2545.         con_write_length, 'con_write_string', \
  2546.         con_printf, 'con_printf', \
  2547.         con_exit, 'con_exit', \
  2548.         con_get_flags, 'con_get_flags', \
  2549.         con_set_flags, 'con_set_flags', \
  2550.         con_kbhit, 'con_kbhit', \
  2551.         con_getch, 'con_getch', \
  2552.         con_getch2, 'con_getch2', \
  2553.         con_gets, 'con_gets', \
  2554.         con_gets2, 'con_gets2', \
  2555.         con_get_font_height, 'con_get_font_height', \
  2556.         con_get_cursor_height, 'con_get_cursor_height', \
  2557.         con_set_cursor_height, 'con_set_cursor_height', \
  2558.         con_cls, 'con_cls', \
  2559.         con_get_cursor_pos, 'con_get_cursor_pos', \
  2560.         con_set_cursor_pos, 'con_set_cursor_pos', \
  2561.         con_set_title, 'con_set_title'
  2562. end data
  2563.  
  2564. version dd 0x00020008
  2565. con.thread_err      db 'Cannot create console thread!',13,10,0
  2566. con.nomem_err       db 'Not enough memory!',13,10,0
  2567. con.aFinished       db ' [Finished]',0
  2568. con.aNull           db '(null)',0
  2569. con.beep                db      0x90, 0x3C, 0x00
  2570.  
  2571. section '.data' data readable writable
  2572. con_flags       dd      ?
  2573. con.cursor_height dd    ?
  2574. con.input_start dd      ?
  2575. con.input_end   dd      ?
  2576.  
  2577. con_esc_attr_n  dd      ?
  2578. con_esc_attrs   dd      ?,?,?,?
  2579. con_esc         db      ?
  2580. con_sci         db      ?
  2581.  
  2582. con.entered_char dw     ?
  2583. con.bGetchRequested db  ?
  2584. con.bWasE0       db     ?
  2585.  
  2586. con.init_cmd db ?
  2587.  
  2588. con.finished_title          rb 256
  2589.  
  2590. con.cur_x                   rd 1
  2591. con.cur_y                   rd 1
  2592. con.wnd_xpos                rd 1
  2593. con.wnd_ypos                rd 1
  2594.  
  2595. con.wnd_width               rd 1
  2596. con.wnd_height              rd 1
  2597. con.scr_width               rd 1
  2598. con.scr_height              rd 1
  2599. con.title                   rd 1
  2600. con.data                    rd 1
  2601. con.image                   rd 1
  2602. con.console_tid             rd 1
  2603. con.data_width              rw 1
  2604. con.data_height             rw 1
  2605. con.vscrollbar_size         rd 1
  2606. con.vscrollbar_pos          rd 1
  2607. con.up_first_time           rd 1
  2608. con.down_first_time         rd 1
  2609. con.scroll_up_first_time    rd 1
  2610. con.scroll_down_first_time  rd 1
  2611. con.bUpPressed_saved        rb 1
  2612. con.bDownPressed_saved      rb 1
  2613. con.bScrollingUp_saved      rb 1
  2614. con.bScrollingDown_saved    rb 1
  2615. con.vscroll_pt      dd    ?
  2616.  
  2617. con.input_buffer                rw      128
  2618. con.input_buffer_end = $
  2619.  
  2620. con.kbd_layout          rb      128
  2621.  
  2622. con.ipc_buf rb 0x11
  2623.  
  2624. ; 1 = exit, 2 = set title, 3 = redraw, 4 = getch
  2625. con.thread_op               rb 1
  2626. con.bUpPressed              rb 1
  2627. con.bDownPressed            rb 1
  2628. con.bScrollingUp            rb 1
  2629. con.bScrollingDown          rb 1
  2630.  
  2631. con.stack                   rb 1024
  2632. con.stack_top = $
  2633.  
  2634. struc process_info
  2635. {
  2636.   cpu_usage               dd ?  ; +0
  2637.   window_stack_position   dw ?  ; +4
  2638.   window_stack_value      dw ?  ; +6
  2639.                           dw ?  ; +8
  2640.   process_name            rb 12 ; +10
  2641.   memory_start            dd ?  ; +22
  2642.   used_memory             dd ?  ; +26
  2643.   PID                     dd ?  ; +30
  2644.   box.x                   dd ?  ; +34
  2645.   box.y                   dd ?  ; +38
  2646.   box.width               dd ?  ; +42
  2647.   box.height              dd ?  ; +46
  2648.   slot_state              dw ?  ; +50
  2649.                           dw ?  ; +52
  2650.   client_box.x            dd ?  ; +54
  2651.   client_box.y            dd ?  ; +58
  2652.   client_box.width        dd ?  ; +62
  2653.   client_box.height       dd ?  ; +66
  2654.   wnd_state               db ?  ; +70
  2655.   rb (1024-71)
  2656. }
  2657. process_info_buffer process_info
  2658. window_status           rd 1
  2659.