Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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