Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1159 hidnplayr 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
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