Subversion Repositories Kolibri OS

Rev

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

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