Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
5363 yogev_ezra 3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
2288 clevermous 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
format MS COFF
9
 
10
DEBUG           equ 1
11
 
12
include 'proc32.inc'
13
include 'imports.inc'
14
 
15
 
16
 
17
API_VERSION       equ 0
18
UART_VERSION      equ API_VERSION
19
 
20
PG_SW             equ 0x003
21
page_tabs         equ 0xFDC00000     ;hack
22
 
23
OS_BASE           equ 0x80000000
24
SLOT_BASE         equ (OS_BASE+0x0080000)
25
TASK_COUNT        equ (OS_BASE+0x0003004)
26
CURRENT_TASK      equ (OS_BASE+0x0003000)
27
 
28
 
29
struc APPOBJ           ;common object header
30
{
31
   .magic       dd ?   ;
32
   .destroy     dd ?   ;internal destructor
33
   .fd          dd ?   ;next object in list
34
   .bk          dd ?   ;prev object in list
35
   .pid         dd ?   ;owner id
36
};
37
 
38
virtual at 0
39
  APPOBJ APPOBJ
40
end virtual
41
 
42
struc IOCTL
43
{  .handle      dd ?
44
   .io_code     dd ?
45
   .input       dd ?
46
   .inp_size    dd ?
47
   .output      dd ?
48
   .out_size    dd ?
49
}
50
 
51
virtual at 0
52
  IOCTL IOCTL
53
end virtual
54
 
55
DEBUG            equ   1
56
 
57
DRV_ENTRY        equ   1
58
DRV_EXIT         equ  -1
59
 
60
THR_REG          equ  0;  x3f8   ;transtitter/reciever
61
IER_REG          equ  1;  x3f9   ;interrupt enable
62
IIR_REG          equ  2;  x3fA   ;interrupt info
63
LCR_REG          equ  3;  x3FB   ;line control
64
MCR_REG          equ  4;  x3FC   ;modem control
65
LSR_REG          equ  5;  x3FD   ;line status
66
MSR_REG          equ  6;  x3FE   ;modem status
67
 
68
LCR_5BIT         equ  0x00
69
LCR_6BIT         equ  0x01
70
LCR_7BIT         equ  0x02
71
LCR_8BIT         equ  0x03
72
LCR_STOP_1       equ  0x00
73
LCR_STOP_2       equ  0x04
74
LCR_PARITY       equ  0x08
75
LCR_EVEN         equ  0x10
76
LCR_STICK        equ  0x20
77
LCR_BREAK        equ  0x40
78
LCR_DLAB         equ  0x80
79
 
80
LSR_DR           equ  0x01     ;data ready
81
LSR_OE           equ  0x02     ;overrun error
82
LSR_PE           equ  0x04     ;parity error
83
LSR_FE           equ  0x08     ;framing error
84
LSR_BI           equ  0x10     ;break interrupt
85
LSR_THRE         equ  0x20     ;transmitter holding empty
86
LSR_TEMT         equ  0x40     ;transmitter empty
87
LSR_FER          equ  0x80     ;FIFO error
88
 
89
FCR_EFIFO        equ  0x01     ;enable FIFO
90
FCR_CRB          equ  0x02     ;clear reciever FIFO
91
FCR_CXMIT        equ  0x04     ;clear transmitter FIFO
92
FCR_RDY          equ  0x08     ;set RXRDY and TXRDY pins
93
FCR_FIFO_1       equ  0x00     ;1  byte trigger
94
FCR_FIFO_4       equ  0x40     ;4  bytes trigger
95
FCR_FIFO_8       equ  0x80     ;8  bytes trigger
96
FCR_FIFO_14      equ  0xC0     ;14 bytes trigger
97
 
98
IIR_INTR         equ  0x01     ;1= no interrupts
99
 
100
IER_RDAI         equ  0x01     ;reciever data interrupt
101
IER_THRI         equ  0x02     ;transmitter empty interrupt
102
IER_LSI          equ  0x04     ;line status interrupt
103
IER_MSI          equ  0x08     ;modem status interrupt
104
 
105
MCR_DTR          equ  0x01     ;0-> DTR=1, 1-> DTR=0
106
MCR_RTS          equ  0x02     ;0-> RTS=1, 1-> RTS=0
107
MCR_OUT_1        equ  0x04     ;0-> OUT1=1, 1-> OUT1=0
108
MCR_OUT_2        equ  0x08     ;0-> OUT2=1, 1-> OUT2=0;  enable intr
109
MCR_LOOP         equ  0x10     ;lopback mode
110
 
111
MSR_DCTS         equ  0x01     ;delta clear to send
112
MSR_DDSR         equ  0x02     ;delta data set redy
113
MSR_TERI         equ  0x04     ;trailinh edge of ring
114
MSR_DDCD         equ  0x08     ;delta carrier detect
115
 
116
 
117
RATE_50          equ  0
118
RATE_75          equ  1
119
RATE_110         equ  2
120
RATE_134         equ  3
121
RATE_150         equ  4
122
RATE_300         equ  5
123
RATE_600         equ  6
124
RATE_1200        equ  7
125
RATE_1800        equ  8
126
RATE_2000        equ  9
127
RATE_2400        equ 10
128
RATE_3600        equ 11
129
RATE_4800        equ 12
130
RATE_7200        equ 13
131
RATE_9600        equ 14
132
RATE_19200       equ 15
133
RATE_38400       equ 16
134
RATE_57600       equ 17
135
RATE_115200      equ 18
136
 
137
COM_1            equ  1
138
COM_2            equ  2
139
COM_3            equ  3
140
COM_4            equ  4
141
COM_MAX          equ  2    ;only two port supported
142
 
143
COM_1_BASE       equ 0x3F8
144
COM_2_BASE       equ 0x2F8
145
 
146
COM_1_IRQ        equ  4
147
COM_2_IRQ        equ  3
148
 
149
UART_CLOSED      equ  0
150
UART_TRANSMIT    equ  1
151
UART_STOP        equ  2
152
 
153
struc UART
154
{
155
   .lock         dd ?
156
   .base         dd ?
157
   .lcr_reg      dd ?
158
   .mcr_reg      dd ?
159
   .rate         dd ?
160
   .mode         dd ?
161
   .state        dd ?
162
 
163
   .rcvr_buff    dd ?
164
   .rcvr_rp      dd ?
165
   .rcvr_wp      dd ?
166
   .rcvr_count   dd ?
167
   .rcvr_top     dd ?
168
 
169
   .xmit_buff    dd ?
170
   .xmit_rp      dd ?
171
   .xmit_wp      dd ?
172
   .xmit_count   dd ?
173
   .xmit_free    dd ?
174
   .xmit_top     dd ?
175
}
176
virtual at 0
177
  UART UART
178
end virtual
179
 
180
UART_SIZE     equ 18*4
181
 
182
struc CONNECTION
183
{
184
   .magic       dd ?   ;'CNCT'
185
   .destroy     dd ?   ;internal destructor
186
   .fd          dd ?   ;next object in list
187
   .bk          dd ?   ;prev object in list
188
   .pid         dd ?   ;owner id
189
 
190
   .id          dd ?   ;reserved
191
   .uart        dd ?   ;uart pointer
192
}
193
 
194
virtual at 0
195
  CONNECTION CONNECTION
196
end virtual
197
 
198
CONNECTION_SIZE equ 7*4
199
 
200
public START
201
public service_proc
202
public version
203
 
204
section '.flat' code readable align 16
205
 
206
proc START stdcall, state:dword
207
 
208
        cmp     [state], 1
209
        jne     .stop
210
 
211
        mov     eax, UART_SIZE
212
        call    Kmalloc
213
        test    eax, eax
214
        jz      .fail
215
 
216
        mov     [com1], eax
217
        mov     edi, eax
218
        mov     ecx, UART_SIZE/4
219
        xor     eax, eax
220
        cld
221
        rep stosd
222
 
223
        mov     eax, [com1]
224
        mov     [eax+UART.base], COM_1_BASE
225
 
226
        stdcall AllocKernelSpace, 32768
227
 
228
        mov     edi, [com1]
229
        mov     edx, eax
230
 
231
        mov     [edi+UART.rcvr_buff], eax
232
        add     eax, 8192
233
        mov     [edi+UART.rcvr_top], eax
234
        add     eax, 8192
235
        mov     [edi+UART.xmit_buff], eax
236
        add     eax, 8192
237
        mov     [edi+UART.xmit_top], eax
238
 
239
        call    AllocPage
240
        test    eax, eax
241
        jz      .fail
242
 
243
        shr     edx, 12
244
        or      eax, PG_SW
245
        mov     [page_tabs+edx*4], eax
246
        mov     [page_tabs+edx*4+8], eax
247
 
248
        call    AllocPage
249
        test    eax, eax
250
        jz      .fail
251
 
252
        or      eax, PG_SW
253
        mov     [page_tabs+edx*4+4], eax
254
        mov     [page_tabs+edx*4+12], eax
255
 
256
        call    AllocPage
257
        test    eax, eax
258
        jz      .fail
259
 
260
        or      eax, PG_SW
261
        mov     [page_tabs+edx*4+16], eax
262
        mov     [page_tabs+edx*4+24], eax
263
 
264
        call    AllocPage
265
        test    eax, eax
266
        jz      .fail
267
 
268
        or      eax, PG_SW
269
        mov     [page_tabs+edx*4+20], eax
270
        mov     [page_tabs+edx*4+28], eax
271
 
272
        mov     eax, [edi+UART.rcvr_buff]
273
        invlpg  [eax]
274
        invlpg  [eax+0x1000]
275
        invlpg  [eax+0x2000]
276
        invlpg  [eax+0x3000]
277
        invlpg  [eax+0x4000]
278
        invlpg  [eax+0x5000]
279
        invlpg  [eax+0x6000]
280
        invlpg  [eax+0x7000]
281
 
282
        mov     eax, edi
283
        call    uart_reset.internal   ;eax= uart
284
 
285
        stdcall AttachIntHandler, COM_1_IRQ, com_1_isr, dword 0
286
        stdcall RegService, sz_uart_srv, service_proc
287
        ret
288
.fail:
289
.stop:
290
        xor     eax, eax
291
        ret
292
endp
293
 
294
 
295
handle     equ  IOCTL.handle
296
io_code    equ  IOCTL.io_code
297
input      equ  IOCTL.input
298
inp_size   equ  IOCTL.inp_size
299
output     equ  IOCTL.output
300
out_size   equ  IOCTL.out_size
301
 
302
SRV_GETVERSION  equ 0
303
PORT_OPEN       equ 1
304
PORT_CLOSE      equ 2
305
PORT_RESET      equ 3
306
PORT_SETMODE    equ 4
307
PORT_GETMODE    equ 5
308
PORT_SETMCR     equ 6
309
PORT_GETMCR     equ 7
310
PORT_READ       equ 8
311
PORT_WRITE      equ 9
312
 
313
align 4
314
proc service_proc stdcall, ioctl:dword
315
 
316
        mov     ebx, [ioctl]
317
        mov     eax, [ebx+io_code]
318
        cmp     eax, PORT_WRITE
319
        ja      .fail
320
 
321
        cmp     eax, SRV_GETVERSION
322
        jne     @F
323
 
324
        mov     eax, [ebx+output]
325
        cmp     [ebx+out_size], 4
326
        jne     .fail
327
        mov     [eax], dword UART_VERSION
328
        xor     eax, eax
329
        ret
330
@@:
331
        cmp     eax, PORT_OPEN
332
        jne     @F
333
 
334
        cmp     [ebx+out_size], 4
335
        jne     .fail
336
 
337
        mov     ebx, [ebx+input]
338
        mov     eax, [ebx]
339
        call    uart_open
340
        mov     ebx, [ioctl]
341
        mov     ebx, [ebx+output]
342
        mov     [ebx], ecx
343
        ret
344
@@:
345
        mov     esi, [ebx+input]    ;input buffer
346
        mov     edi, [ebx+output]
347
        call    [uart_func+eax*4]
348
        ret
349
.fail:
350
        or      eax, -1
351
        ret
352
 
353
endp
354
 
355
restore   handle
356
restore   io_code
357
restore   input
358
restore   inp_size
359
restore   output
360
restore   out_size
361
 
362
 
363
; param
364
;  esi=  input buffer
365
;        +0 connection
366
;
367
; retval
368
;  eax= error code
369
 
370
align 4
371
uart_reset:
372
        mov     eax, [esi]
373
        cmp     [eax+APPOBJ.magic], 'CNCT'
374
        jne     .fail
375
 
376
        cmp     [eax+APPOBJ.destroy], uart_close.destroy
377
        jne     .fail
378
 
379
        mov     eax, [eax+CONNECTION.uart]
380
        test    eax, eax
381
        jz      .fail
382
 
383
; set mode 2400 bod 8-bit
384
; disable DTR & RTS
385
; clear FIFO
386
; clear pending interrupts
387
;
388
; param
389
;  eax= uart
390
 
391
align 4
392
.internal:
393
        mov     esi, eax
394
        mov     [eax+UART.state], UART_CLOSED
395
        mov     edx, [eax+UART.base]
396
        add     edx, MCR_REG
397
        xor     eax, eax
398
        out     dx, al       ;clear DTR & RTS
399
 
400
        mov     eax, esi
401
        mov     ebx, RATE_2400
402
        mov     ecx, LCR_8BIT+LCR_STOP_1
403
        call    uart_set_mode.internal
404
 
405
        mov     edx, [esi+UART.base]
406
        add     edx, IIR_REG
407
        mov     eax, FCR_EFIFO+FCR_CRB+FCR_CXMIT+FCR_FIFO_14
408
        out     dx, al
409
.clear_RB:
410
        mov     edx, [esi+UART.base]
411
        add     edx, LSR_REG
412
        in      al, dx
413
        test    eax, LSR_DR
414
        jz      @F
415
 
416
        mov     edx, [esi+UART.base]
417
        in      al, dx
418
        jmp     .clear_RB
419
@@:
420
        mov     edx, [esi+UART.base]
421
        add     edx, IER_REG
422
        mov     eax, IER_RDAI+IER_THRI+IER_LSI
423
        out     dx, al
424
.clear_IIR:
425
        mov     edx, [esi+UART.base]
426
        add     edx, IIR_REG
427
        in      al, dx
428
        test    al, IIR_INTR
429
        jnz     .done
430
 
431
        shr     eax, 1
432
        and     eax, 3
433
        jnz     @F
434
 
435
        mov     edx, [esi+UART.base]
436
        add     edx, MSR_REG
437
        in      al, dx
438
        jmp     .clear_IIR
439
@@:
440
        cmp     eax, 1
441
        je      .clear_IIR
442
 
443
        cmp     eax, 2
444
        jne     @F
445
 
446
        mov     edx, [esi+UART.base]
447
        in      al, dx
448
        jmp     .clear_IIR
449
@@:
450
        mov     edx, [esi+UART.base]
451
        add     edx, LSR_REG
452
        in      al, dx
453
        jmp     .clear_IIR
454
.done:
455
        mov     edi, [esi+UART.rcvr_buff]
456
        mov     ecx, 8192/4
457
        xor     eax, eax
458
 
459
        mov     [esi+UART.rcvr_rp], edi
460
        mov     [esi+UART.rcvr_wp], edi
461
        mov     [esi+UART.rcvr_count], eax
462
 
463
        cld
464
        rep stosd
465
 
466
        mov     edi, [esi+UART.xmit_buff]
467
        mov     ecx, 8192/4
468
 
469
        mov     [esi+UART.xmit_rp], edi
470
        mov     [esi+UART.xmit_wp], edi
471
        mov     [esi+UART.xmit_count], eax
472
        mov     [esi+UART.xmit_free], 8192
473
 
474
        rep stosd
475
        ret                  ;eax= 0
476
.fail:
477
        or      eax, -1
478
        ret
479
 
480
; param
481
;  esi=  input buffer
482
;        +0 connection
483
;        +4 rate
484
;        +8 mode
485
;
486
; retval
487
;  eax= error code
488
 
489
align 4
490
uart_set_mode:
491
        mov     eax, [esi]
492
        cmp     [eax+APPOBJ.magic], 'CNCT'
493
        jne     .fail
494
 
495
        cmp     [eax+APPOBJ.destroy], uart_close.destroy
496
        jne     .fail
497
 
498
        mov     eax, [eax+CONNECTION.uart]
499
        test    eax, eax
500
        jz      .fail
501
 
502
        mov     ebx, [esi+4]
503
        mov     ecx, [esi+8]
504
 
505
; param
506
;  eax= uart
507
;  ebx= baud rate
508
;  ecx= mode
509
 
510
align 4
511
.internal:
512
        cmp     ebx, RATE_115200
513
        ja      .fail
514
 
515
        cmp     ecx, LCR_BREAK
516
        jae     .fail
517
 
518
        mov     [eax+UART.rate], ebx
519
        mov     [eax+UART.mode], ecx
520
 
521
        mov     esi, eax
522
        mov     bx, [divisor+ebx*2]
523
 
524
        mov     edx, [esi+UART.base]
525
        push    edx
526
        add     edx, LCR_REG
527
        in      al, dx
528
        or      al, 0x80
529
        out     dx, al
530
 
531
        pop     edx
532
        mov     al, bl
533
        out     dx, al
534
 
535
        inc     dx
536
        mov     al, bh
537
        out     dx, al
538
 
539
        add     edx, LCR_REG-1
540
        mov     eax, ecx
541
        out     dx, al
542
        xor     eax, eax
543
        ret
544
.fail:
545
        or      eax, -1
546
        ret
547
 
548
; param
549
;  esi=  input buffer
550
;        +0 connection
551
;        +4 modem control reg valie
552
;
553
; retval
554
;  eax= error code
555
 
556
align 4
557
uart_set_mcr:
558
 
559
        mov     eax, [esi]
560
        cmp     [eax+APPOBJ.magic], 'CNCT'
561
        jne     .fail
562
 
563
        cmp     [eax+APPOBJ.destroy], uart_close.destroy
564
        jne     .fail
565
 
566
        mov     eax, [eax+CONNECTION.uart]
567
        test    eax, eax
568
        jz      .fail
569
 
570
        mov     ebx, [esi+4]
571
 
572
        mov     [eax+UART.mcr_reg], ebx
573
        mov     edx, [eax+UART.base]
574
        add     edx, MCR_REG
575
        mov     al, bl
576
        out     dx, al
577
        xor     eax, eax
578
        ret
579
.fail:
580
        or      eax, -1
581
        ret
582
 
583
; param
584
;  eax= port
585
;
586
; retval
587
;  ecx= connection
588
;  eax= error code
589
 
590
align 4
591
uart_open:
592
        dec     eax
593
        cmp     eax, COM_MAX
594
        jae     .fail
595
 
596
        mov     esi, [com1+eax*4]            ;uart
597
        push    esi
598
.do_wait:
599
        cmp     dword [esi+UART.lock], 0
600
        je      .get_lock
601
      ;     call change_task
602
        jmp     .do_wait
603
.get_lock:
604
        mov     eax, 1
605
        xchg    eax, [esi+UART.lock]
606
        test    eax, eax
607
        jnz     .do_wait
608
 
609
        mov     eax, esi                 ;uart
610
        call    uart_reset.internal
611
 
612
        mov     ebx, [CURRENT_TASK]
613
        shl     ebx, 5
614
        mov     ebx, [CURRENT_TASK+ebx+4]
615
        mov     eax, CONNECTION_SIZE
616
        call    CreateObject
617
        pop     esi                      ;uart
618
        test    eax, eax
619
        jz      .fail
620
 
621
        mov     [eax+APPOBJ.magic], 'CNCT'
622
        mov     [eax+APPOBJ.destroy], uart_close.destroy
623
        mov     [eax+CONNECTION.uart], esi
624
        mov     ecx, eax
625
        xor     eax, eax
626
        ret
627
.fail:
628
        or      eax, -1
629
        ret
630
restore .uart
631
 
632
; param
633
;  esi= input buffer
634
 
635
align 4
636
uart_close:
637
        mov     eax, [esi]
638
        cmp     [eax+APPOBJ.magic], 'CNCT'
639
        jne     .fail
640
 
641
        cmp     [eax+APPOBJ.destroy], uart_close.destroy
642
        jne     .fail
643
.destroy:
644
        push    [eax+CONNECTION.uart]
645
        call    DestroyObject   ;eax= object
646
        pop     eax                     ;eax= uart
647
        test    eax, eax
648
        jz      .fail
649
 
650
        mov     [eax+UART.state], UART_CLOSED
651
        mov     [eax+UART.lock], 0;release port
652
        xor     eax, eax
653
        ret
654
.fail:
655
        or      eax, -1
656
        ret
657
 
658
 
659
; param
660
;  eax= uart
661
;  ebx= baud rate
662
 
663
align 4
664
set_rate:
665
        cmp     ebx, RATE_115200
666
        ja      .fail
667
 
668
        mov     [eax+UART.rate], ebx
669
        mov     bx, [divisor+ebx*2]
670
 
671
        mov     edx, [eax+UART.base]
672
        add     edx, LCR_REG
673
        in      al, dx
674
        push    eax
675
        or      al, 0x80
676
        out     dx, al
677
 
678
        sub     edx, LCR_REG
679
        mov     al, bl
680
        out     dx, al
681
 
682
        inc     edx
683
        mov     al, bh
684
        out     dx, al
685
 
686
        pop     eax
687
        add     edx, LCR_REG-1
688
        out     dx, al
689
.fail:
690
        ret
691
 
692
 
693
; param
694
;   ebx= uart
695
 
696
align 4
697
transmit:
698
        push    esi
699
        push    edi
700
 
701
        mov     edx, [ebx+UART.base]
702
 
703
        pushfd
704
        cli
705
 
706
        mov     esi, [ebx+UART.xmit_rp]
707
        mov     ecx, [ebx+UART.xmit_count]
708
        test    ecx, ecx
709
        je      .stop
710
 
711
        cmp     ecx, 16
712
        jbe     @F
713
        mov     ecx, 16
714
@@:
715
        sub     [ebx+UART.xmit_count], ecx
716
        add     [ebx+UART.xmit_free], ecx
717
        cld
718
@@:
719
        lodsb
720
        out     dx, al
721
        dec     ecx
722
        jnz     @B
723
 
724
        cmp     esi, [ebx+UART.xmit_top]
725
        jb      @F
726
        sub     esi, 8192
727
@@:
728
        mov     [ebx+UART.xmit_rp], esi
729
 
730
        cmp     [ebx+UART.xmit_count], 0
731
        je      .stop
732
 
733
        mov     [ebx+UART.state], UART_TRANSMIT
734
        jmp     @F
735
.stop:
736
        mov     [ebx+UART.state], UART_STOP
737
@@:
738
        popfd
739
        pop     edi
740
        pop     esi
741
        ret
742
 
743
 
744
; param
745
;  esi=  input buffer
746
;        +0 connection
747
;        +4 dst buffer
748
;        +8 dst size
749
;  edi=  output buffer
750
;        +0 bytes read
751
 
752
; retval
753
;  eax= error code
754
 
755
align 4
756
uart_read:
757
        mov     eax, [esi]
758
        cmp     [eax+APPOBJ.magic], 'CNCT'
759
        jne     .fail
760
 
761
        cmp     [eax+APPOBJ.destroy], uart_close.destroy
762
        jne     .fail
763
 
764
        mov     eax, [eax+CONNECTION.uart]
765
        test    eax, eax
766
        jz      .fail
767
 
768
        mov     ebx, [esi+8]   ;dst size
769
        mov     ecx, [eax+UART.rcvr_count]
770
        cmp     ecx, ebx
771
        jbe     @F
772
        mov     ecx, ebx
773
@@:
774
        mov     [edi], ecx     ;bytes read
775
        test    ecx, ecx
776
        jz      .done
777
 
778
        push    ecx
779
 
780
        mov     edi, [esi+4]   ;dst
781
        mov     esi, [eax+UART.rcvr_rp]
782
        cld
783
        rep movsb
784
        pop     ecx
785
 
786
        cmp     esi, [eax+UART.rcvr_top]
787
        jb      @F
788
        sub     esi, 8192
789
@@:
790
        mov     [eax+UART.rcvr_rp], esi
791
        sub     [eax+UART.rcvr_count], ecx
792
.done:
793
        xor     eax, eax
794
        ret
795
.fail:
796
        or      eax, -1
797
        ret
798
 
799
; param
800
;  esi=  input buffer
801
;        +0 connection
802
;        +4 src buffer
803
;        +8 src size
804
;
805
; retval
806
;  eax= error code
807
 
808
align 4
809
uart_write:
810
        mov     eax, [esi]
811
        cmp     [eax+APPOBJ.magic], 'CNCT'
812
        jne     .fail
813
 
814
        cmp     [eax+APPOBJ.destroy], uart_close.destroy
815
        jne     .fail
816
 
817
        mov     eax, [eax+CONNECTION.uart]
818
        test    eax, eax
819
        jz      .fail
820
 
821
        mov     ebx, [esi+4]
822
        mov     edx, [esi+8]
823
 
824
; param
825
;  eax= uart
826
;  ebx= src
827
;  edx= count
828
 
829
align 4
830
.internal:
831
        mov     esi, ebx
832
        mov     edi, [eax+UART.xmit_wp]
833
.write:
834
        test    edx, edx
835
        jz      .fail
836
.wait:
837
        cmp     [eax+UART.xmit_free], 0
838
        jne     .fill
839
 
840
        cmp     [eax+UART.state], UART_TRANSMIT
841
        je      .wait
842
 
843
        mov     ebx, eax
844
        push    edx
845
        call    transmit
846
        pop     edx
847
        mov     eax, ebx
848
        jmp     .write
849
.fill:
850
        mov     ecx, [eax+UART.xmit_free]
851
        cmp     ecx, edx
852
        jbe     @F
853
        mov     ecx, edx
854
@@:
855
        push    ecx
856
        cld
857
        rep movsb
858
        pop     ecx
859
        sub     [eax+UART.xmit_free], ecx
860
        add     [eax+UART.xmit_count], ecx
861
        sub     edx, ecx
862
        jnz     .wait
863
.done:
864
        cmp     edi, [eax+UART.xmit_top]
865
        jb      @F
866
        sub     edi, 8192
867
@@:
868
        mov     [eax+UART.xmit_wp], edi
869
        cmp     [eax+UART.state], UART_TRANSMIT
870
        je      @F
871
        mov     ebx, eax
872
        call    transmit
873
@@:
874
        xor     eax, eax
875
        ret
876
.fail:
877
        or      eax, -1
878
        ret
879
 
880
 
881
align 4
882
com_2_isr:
883
        mov     ebx, [com2]
884
        jmp     com_1_isr.get_info
885
align 4
886
com_1_isr:
887
        mov     ebx, [com1]
888
.get_info:
889
        mov     edx, [ebx+UART.base]
890
        add     edx, IIR_REG
891
        in      al, dx
892
 
893
        test    al, IIR_INTR
894
        jnz     .done
895
 
896
        shr     eax, 1
897
        and     eax, 3
898
 
899
        call    [isr_action+eax*4]
900
        jmp     .get_info
901
.done:
902
        ret
903
 
904
align 4
905
isr_line:
906
        mov     edx, [ebx+UART.base]
907
        add     edx, LSR_REG
908
        in      al, dx
909
        ret
910
 
911
align 4
912
isr_recieve:
913
        mov     esi, [ebx+UART.base]
914
        add     esi, LSR_REG
915
        mov     edi, [ebx+UART.rcvr_wp]
916
        xor     ecx, ecx
917
        cld
918
.read:
919
        mov     edx, esi
920
        in      al, dx
921
        test    eax, LSR_DR
922
        jz      .done
923
 
924
        mov     edx, [ebx+UART.base]
925
        in      al, dx
926
        stosb
927
        inc     ecx
928
        jmp     .read
929
.done:
930
        cmp     edi, [ebx+UART.rcvr_top]
931
        jb      @F
932
        sub     edi, 8192
933
@@:
934
        mov     [ebx+UART.rcvr_wp], edi
935
        add     [ebx+UART.rcvr_count], ecx
936
        ret
937
 
938
align 4
939
isr_modem:
940
        mov     edx, [ebx+UART.base]
941
        add     edx, MSR_REG
942
        in      al, dx
943
        ret
944
 
945
 
946
align 4
947
divisor    dw 2304, 1536, 1047, 857, 768, 384
948
           dw  192,   96,   64,  58,  48,  32
949
           dw   24,   16,   12,   6,   3,   2, 1
950
 
951
align 4
952
uart_func   dd 0                ;SRV_GETVERSION
953
            dd 0                ;PORT_OPEN
954
            dd uart_close       ;PORT_CLOSE
955
            dd uart_reset       ;PORT_RESET
956
            dd uart_set_mode    ;PORT_SETMODE
957
            dd 0                ;PORT_GETMODE
958
            dd uart_set_mcr     ;PORT_SETMODEM
959
            dd 0                ;PORT_GETMODEM
960
            dd uart_read        ;PORT_READ
961
            dd uart_write       ;PORT_WRITE
962
 
963
isr_action  dd isr_modem
964
            dd transmit
965
            dd isr_recieve
966
            dd isr_line
967
 
968
version     dd (5 shl 16) or (UART_VERSION and 0xFFFF)
969
 
970
sz_uart_srv db 'UART',0
971
 
972
align 4
973
 
974
com1        rd 1
975
com2        rd 1
976