Subversion Repositories Kolibri OS

Rev

Rev 8328 | Rev 9105 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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