Subversion Repositories Kolibri OS

Rev

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