Subversion Repositories Kolibri OS

Rev

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