Subversion Repositories Kolibri OS

Rev

Rev 852 | Rev 1134 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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