Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
405 serge 1
 
2
;new_app_base    equ 0x60400000
3
;PROC_BASE       equ OS_BASE+0x0080000
4
5
 
6
{  .handle      dd ?
7
   .io_code     dd ?
8
   .input       dd ?
9
   .inp_size    dd ?
10
   .output      dd ?
11
   .out_size    dd ?
12
}
13
14
 
15
 
16
;public service_proc
17
;public version
18
19
 
20
21
 
22
DRV_EXIT         equ  -1
23
24
 
413 serge 25
IER_REG          equ  1;  x3f9   ;interrupt enable
26
IIR_REG          equ  2;  x3fA   ;interrupt info
27
LCR_REG          equ  3;  x3FB   ;line control
28
MCR_REG          equ  4;  x3FC   ;modem control
29
LSR_REG          equ  5;  x3FD   ;line status
30
MSR_REG          equ  6;  x3FE   ;modem status
31
405 serge 32
 
33
LCR_6BIT         equ  0x01
34
LCR_7BIT         equ  0x02
35
LCR_8BIT         equ  0x03
36
LCR_STOP_1       equ  0x00
37
LCR_STOP_2       equ  0x04
38
LCR_PARITY       equ  0x08
39
LCR_EVEN         equ  0x10
40
LCR_STICK        equ  0x20
41
LCR_BREAK        equ  0x40
42
LCR_DLAB         equ  0x80
43
44
 
45
LSR_OE           equ  0x02     ;overrun error
46
LSR_PE           equ  0x04     ;parity error
47
LSR_FE           equ  0x08     ;framing error
48
LSR_BI           equ  0x10     ;break interrupt
49
LSR_THRE         equ  0x20     ;transmitter holding empty
50
LSR_TEMT         equ  0x40     ;transmitter empty
51
LSR_FER          equ  0x80     ;FIFO error
52
53
 
54
FCR_CRB          equ  0x02     ;clear reciever FIFO
55
FCR_CXMIT        equ  0x04     ;clear transmitter FIFO
56
FCR_RDY          equ  0x08     ;set RXRDY and TXRDY pins
57
FCR_FIFO_1       equ  0x00     ;1  byte trigger
58
FCR_FIFO_4       equ  0x40     ;4  bytes trigger
59
FCR_FIFO_8       equ  0x80     ;8  bytes trigger
60
FCR_FIFO_14      equ  0xC0     ;14 bytes trigger
61
62
 
63
64
 
65
IER_THRI         equ  0x02     ;transmitter empty interrupt
66
IER_LSI          equ  0x04     ;line status interrupt
67
IER_MSI          equ  0x08     ;modem status interrupt
68
69
 
70
MCR_RTS          equ  0x02     ;0-> RTS=1, 1-> RTS=0
71
MCR_OUT_1        equ  0x04     ;0-> OUT1=1, 1-> OUT1=0
72
MCR_OUT_2        equ  0x08     ;0-> OUT2=1, 1-> OUT2=0  enable intr
413 serge 73
MCR_LOOP         equ  0x10     ;lopback mode
405 serge 74
75
 
76
MSR_DDSR         equ  0x02     ;delta data set redy
77
MSR_TERI         equ  0x04     ;trailinh edge of ring
78
MSR_DDCD         equ  0x08     ;delta carrier detect
79
80
 
81
 
82
RATE_75          equ  1
83
RATE_110         equ  2
84
RATE_134         equ  3
85
RATE_150         equ  4
86
RATE_300         equ  5
87
RATE_600         equ  6
88
RATE_1200        equ  7
89
RATE_1800        equ  8
90
RATE_2000        equ  9
91
RATE_2400        equ 10
92
RATE_3600        equ 11
93
RATE_4800        equ 12
94
RATE_7200        equ 13
95
RATE_9600        equ 14
96
RATE_19200       equ 15
97
RATE_38400       equ 16
98
RATE_57600       equ 17
99
RATE_115200      equ 18
100
101
 
413 serge 102
COM_2            equ  2
103
COM_3            equ  3
104
COM_4            equ  4
105
COM_MAX          equ  2    ;only two port supported
106
405 serge 107
 
413 serge 108
COM_2_BASE       equ 0x2F8
109
110
 
405 serge 111
COM_2_IRQ        equ  3
112
113
 
413 serge 114
UART_TRANSMIT    equ  1
115
405 serge 116
 
413 serge 117
{
405 serge 118
  ; .owner        dd ?   unused
413 serge 119
   .lock         dd ?
120
   .base         dd ?
405 serge 121
   .lcr_reg      dd ?
122
   .mcr_reg      dd ?
123
   .rate         dd ?
124
   .mode         dd ?
125
   .state        dd ?
126
127
 
128
   .rcvr_wp      dd ?
129
   .rcvr_free    dd ?
130
131
 
132
   .xmit_wp      dd ?
133
   .xmit_free    dd ?
134
   .rcvr_buffer  rb 128
413 serge 135
   .xmit_buffer  rb 128
405 serge 136
}
137
virtual at 0
138
  UART UART
413 serge 139
end virtual
405 serge 140
141
 
413 serge 142
XMIT_OFFSET   equ (13*4*128)
143
UART_SIZE     equ (256+13*4)
144
405 serge 145
 
413 serge 146
{
147
   .magic       dd ?   ;'CNCT'
148
   .destroy     dd ?   ;internal destructor
149
   .fd          dd ?   ;next object in list
150
   .bk          dd ?   ;prev object in list
151
   .pid         dd ?   ;owner id
152
405 serge 153
 
413 serge 154
   .uart        dd ?   ;uart pointer
155
}
156
157
 
158
  CONNECTION CONNECTION
159
end virtual
160
161
 
162
163
 
164
165
 
166
           mov eax, UART_SIZE
167
           call malloc
405 serge 168
           test eax, eax
169
           jz .fail
170
171
 
172
           mov edi, eax
173
           mov ecx, UART_SIZE/4
413 serge 174
           xor eax, eax
405 serge 175
           cld
176
           rep stosd
177
178
 
413 serge 179
           mov [eax+UART.base], COM_1_BASE
180
405 serge 181
 
413 serge 182
183
 
184
           stdcall reg_service, sz_uart_srv, uart_proc
405 serge 185
           ret
186
.fail:
187
           xor eax, eax
188
           ret
189
190
 
191
io_code    equ  IOCTL.io_code
192
input      equ  IOCTL.input
193
inp_size   equ  IOCTL.inp_size
194
output     equ  IOCTL.output
195
out_size   equ  IOCTL.out_size
196
197
 
198
PORT_OPEN       equ 1
199
PORT_CLOSE      equ 2
200
PORT_RESET      equ 3
201
PORT_SETMODE    equ 4
202
PORT_GETMODE    equ 5
203
PORT_SETMCR     equ 6
204
PORT_GETMCR     equ 7
205
PORT_READ       equ 8
206
PORT_WRITE      equ 9
207
208
 
209
proc uart_proc stdcall, ioctl:dword
210
211
 
212
           mov eax, [ebx+io_code]
213
           cmp eax, PORT_WRITE
214
           ja .fail
215
216
 
217
           jne @F
218
219
 
220
           mov [eax], dword UART_VERSION
221
           xor eax, eax
222
           ret
223
@@:
224
           cmp eax, PORT_OPEN
225
           jne @F
226
227
 
413 serge 228
           mov eax, [ebx]
229
           call uart_open
230
           mov ebx, [ioctl]
231
           mov ebx, [ebx+output]
232
           mov [ebx], ecx
233
           ret
405 serge 234
@@:
413 serge 235
           mov esi, [ebx+input]     ;input buffer
236
           call [uart_func+eax*4]
237
           ret
238
.fail:
405 serge 239
           or eax, -1
240
           ret
241
242
 
243
244
 
245
restore   io_code
246
restore   input
247
restore   inp_size
248
restore   output
249
restore   out_size
250
251
 
252
 
413 serge 253
; disable DTR & RTS
254
; clear FIFO
255
; clear pending interrupts
256
;
257
; param
405 serge 258
;  eax= uart
413 serge 259
405 serge 260
 
261
uart_reset:
413 serge 262
           mov esi, eax
263
           mov [eax+UART.state], UART_CLOSED
264
           mov edx, [eax+UART.base]
265
           add edx, MCR_REG
266
           xor eax, eax
405 serge 267
           out dx, al        ;clear DTR & RTS
413 serge 268
405 serge 269
 
413 serge 270
           mov ebx, RATE_2400
271
           mov ecx, LCR_8BIT+LCR_STOP_1
272
           call uart_set_mode.internal
273
405 serge 274
 
413 serge 275
           add edx, IIR_REG
276
           mov eax,FCR_EFIFO+FCR_CRB+FCR_CXMIT+FCR_FIFO_14
405 serge 277
           out dx, al
278
.clear_RB:
279
           mov edx, [esi+UART.base]
413 serge 280
           add edx, LSR_REG
281
           in al, dx
405 serge 282
           test eax, LSR_DR
283
           jz @F
284
285
 
413 serge 286
           in al, dx
405 serge 287
           jmp .clear_RB
288
@@:
289
           mov edx, [esi+UART.base]
413 serge 290
           add edx, IER_REG
291
           mov eax,IER_RDAI+IER_THRI+IER_LSI
405 serge 292
           out dx, al
293
.clear_IIR:
294
           mov edx, [esi+UART.base]
413 serge 295
           add edx, IIR_REG
296
           in al, dx
405 serge 297
           test al, IIR_INTR
298
           jnz .done
299
300
 
301
           and eax, 3
302
           jnz @F
303
304
 
413 serge 305
           add edx, MSR_REG
306
           in al, dx
405 serge 307
           jmp .clear_IIR
308
@@:
309
           cmp eax, 1
310
           je .clear_IIR
311
312
 
313
           jne @F
314
315
 
413 serge 316
           in al, dx
405 serge 317
           jmp .clear_IIR
318
@@:
319
           mov edx, [esi+UART.base]
413 serge 320
           add edx, LSR_REG
321
           in al, dx
405 serge 322
           jmp .clear_IIR
323
.done:
324
           lea edi, [esi+UART.rcvr_buffer]
413 serge 325
           mov ecx, 256/4
326
           xor eax, eax
405 serge 327
328
 
413 serge 329
           mov [esi+UART.rcvr_wp], eax
330
           mov [esi+UART.rcvr_free], 128
331
           mov [esi+UART.xmit_rp], eax
332
           mov [esi+UART.xmit_wp], eax
333
           mov [esi+UART.xmit_free], 128
334
405 serge 335
 
336
           rep stosd
337
           ret
338
339
 
413 serge 340
 
405 serge 341
;  esi=  input buffer
413 serge 342
;        +0 connection
343
;        +4 rate
344
;        +8 mode
345
;
346
; retval
347
;  eax= error code
348
405 serge 349
 
350
uart_set_mode:
413 serge 351
           mov eax, [esi]
352
           cmp [eax+APPOBJ.magic], 'CNCT'
353
           jne .fail
354
355
 
356
           jne .fail
357
358
 
359
           test eax, eax
360
           jz .fail
361
362
 
363
           mov ecx, [esi+8]
364
365
 
366
;  eax= uart
367
;  ebx= baud rate
368
;  ecx= mode
369
370
 
371
.internal:
372
           cmp ebx, RATE_115200
373
           ja .fail
405 serge 374
375
 
413 serge 376
           jae .fail
405 serge 377
378
 
413 serge 379
           mov [eax+UART.mode], ecx
380
405 serge 381
 
413 serge 382
           mov bx, [divisor+ebx*2]
383
405 serge 384
 
413 serge 385
           push edx
386
           add edx, LCR_REG
387
           in al, dx
405 serge 388
           or al, 0x80
389
           out dx, al
390
391
 
413 serge 392
           mov al, bl
393
           out dx, al
405 serge 394
395
 
396
           mov al, bh
413 serge 397
           out dx, al
405 serge 398
399
 
413 serge 400
           mov eax, ecx
401
           out dx, al
405 serge 402
           xor eax, eax
413 serge 403
           ret
404
.fail:
405 serge 405
           or eax, -1
413 serge 406
           ret
405 serge 407
408
 
413 serge 409
 
410
uart_set_modem:
411
412
 
413
           mov edx, [eax+UART.base]
414
           add edx, MCR_REG
415
           mov al, bl
416
           out dx, al
417
           ret
418
419
 
405 serge 420
;  eax= port
413 serge 421
;
422
; retval
423
;  ecx= connection
424
;  eax= error code
425
405 serge 426
 
427
uart_open:
413 serge 428
           dec eax
429
           cmp eax, COM_MAX
430
           jae .fail
431
432
 
433
           push esi
434
.do_wait:
435
           cmp dword [esi+UART.lock],0
436
           je .get_lock
437
           call change_task
438
           jmp .do_wait
439
.get_lock:
440
           mov eax, 1
441
           xchg eax, [esi+UART.lock]
442
           test eax, eax
443
           jnz .do_wait
444
445
 
446
           call uart_reset
447
448
 
449
           shl ebx, 5
450
           mov ebx, [CURRENT_TASK+ebx+4]
451
           mov eax, CONNECTION_SIZE
452
           call create_kernel_object
453
           pop esi                       ;uart
454
           test eax, eax
455
           jz .fail
456
457
 
458
           mov [eax+APPOBJ.destroy], uart_close.destroy
459
           mov [eax+CONNECTION.uart], esi
460
           mov ecx, eax
461
           xor eax, eax
462
           ret
463
.fail:
464
           or eax, -1
465
           ret
466
restore .uart
467
468
 
469
;  esi= input buffer
470
471
 
472
uart_close:
473
           mov eax, [esi]
474
           cmp [eax+APPOBJ.magic], 'CNCT'
475
           jne .fail
476
477
 
478
           jne .fail
479
.destroy:
480
           push [eax+CONNECTION.uart]
481
           call destroy_kernel_object   ;eax= object
482
           pop eax                      ;eax= uart
483
           test eax, eax
484
           jz .fail
485
486
 
487
           mov [eax+UART.lock], 0 ;release port
488
           xor eax, eax
489
           ret
490
.fail:
491
           or eax, -1
492
           ret
493
494
 
495
 
496
;  eax= uart
497
;  ebx= baud rate
498
499
 
500
set_rate:
405 serge 501
           cmp ebx, RATE_115200
413 serge 502
           ja .fail
405 serge 503
504
 
413 serge 505
           mov bx, [divisor+ebx*2]
506
405 serge 507
 
413 serge 508
           add edx, LCR_REG
509
           in al, dx
405 serge 510
           push eax
413 serge 511
           or al, 0x80
405 serge 512
           out dx, al
513
514
 
413 serge 515
           mov al, bl
405 serge 516
           out dx, al
517
518
 
413 serge 519
           mov al, bh
405 serge 520
           out dx, al
521
522
 
413 serge 523
           add edx, LCR_REG-1
524
           out dx, al
405 serge 525
.fail:
526
           ret
527
528
 
413 serge 529
 
530
;   ebx= uart
531
532
 
405 serge 533
transmit:
534
           push esi
535
           push edi
413 serge 536
           push ebp
537
405 serge 538
 
413 serge 539
405 serge 540
 
541
           cli
542
543
 
413 serge 544
           mov esi, [ebx+UART.xmit_rp]
545
           lea edi, [ebx+UART.xmit_buffer]
546
           mov ecx, [ebx+UART.xmit_free]
547
405 serge 548
 
549
           je .exit
550
@@:
551
           and esi, 127
552
           mov al, [esi+edi]
413 serge 553
           inc esi
405 serge 554
555
 
556
           inc ecx
557
           dec ebp
413 serge 558
           jz .done
405 serge 559
560
 
561
           jne @B
562
.done:
563
           mov [ebx+UART.xmit_rp], esi
413 serge 564
           mov [ebx+UART.xmit_free], ecx
565
           mov [ebx+UART.state], UART_TRANSMIT
566
.exit:
405 serge 567
           popfd
568
           pop ebp
413 serge 569
           pop edi
570
           pop esi
405 serge 571
           ret
572
573
 
413 serge 574
;  eax= uart
575
;  ebx= src
576
;  edx= count
577
405 serge 578
 
579
uart_write:
413 serge 580
           mov esi, ebx
581
           mov edi, [eax+UART.xmit_wp]
582
           lea ebx, [eax+UART.xmit_buffer]
583
.write:
405 serge 584
           test edx, edx
413 serge 585
           jz .done
405 serge 586
.wait:
587
           cmp [eax+UART.xmit_free], 0
413 serge 588
           jne .fill
405 serge 589
590
 
413 serge 591
           je .wait
405 serge 592
593
 
413 serge 594
           push edx
595
           call transmit
405 serge 596
           pop edx
413 serge 597
           mov eax, ebx
598
           lea ebx, [ebx+UART.xmit_buffer]
599
           jmp .write
405 serge 600
.fill:
601
           mov ecx, 128
413 serge 602
           sub ecx, edi
405 serge 603
           jz .clip
413 serge 604
           cmp ecx, [eax+UART.xmit_free]
605
           jbe @F
606
405 serge 607
 
413 serge 608
@@:
405 serge 609
           cmp ecx, edx
413 serge 610
           jbe @F
611
           mov ecx, edx
612
@@:
405 serge 613
           sub [eax+UART.xmit_free], ecx
413 serge 614
           sub edx, ecx
615
405 serge 616
 
413 serge 617
           cld
405 serge 618
           rep movsb
619
620
 
413 serge 621
.clip:
622
           and edi, 127
623
           jmp .write
405 serge 624
.done:
625
           mov [eax+UART.xmit_wp], edi
413 serge 626
           cmp [eax+UART.state], UART_TRANSMIT
627
           je @F
405 serge 628
           mov ebx, eax
413 serge 629
           call transmit
405 serge 630
@@:
631
           ret
632
633
 
634
com_2_isr:
413 serge 635
           mov ebx, [com2]
636
           jmp com_1_isr.get_info
637
align 4
638
com_1_isr:
639
           mov ebx, [com1]
640
405 serge 641
 
642
           mov edx, [ebx+UART.base]
413 serge 643
           add edx, IIR_REG
644
           in  al, dx
405 serge 645
646
 
647
           jnz .done
648
649
 
650
           and eax, 3
651
652
 
653
           jmp .get_info
654
.done:
655
           ret
656
657
 
658
isr_line:
659
           mov edx, [ebx+UART.base]
413 serge 660
           add edx, LSR_REG
661
           in al, dx
405 serge 662
           ret
663
664
 
665
isr_recieve:
666
           mov edx, [ebx+UART.base]
413 serge 667
           in al, dx
405 serge 668
           ret
669
670
 
671
isr_modem:
672
           mov edx, [ebx+UART.base]
413 serge 673
           add edx, MSR_REG
674
           in al, dx
675
           ret
676
405 serge 677
 
678
 
413 serge 679
com1        dd 0
680
com2        dd 0
681
405 serge 682
 
683
uart_func   dd 0                ;SRV_GETVERSION
413 serge 684
            dd 0                ;PORT_OPEN
685
            dd uart_close       ;PORT_CLOSE
686
            dd 0                ;PORT_RESET
687
            dd uart_set_mode    ;PORT_SETMODE
688
;            dd uart.get_mode    ;PORT_GETMODE
689
;            dd uart.set_mcr     ;PORT_SETMCR
690
;PORT_GETMCR     equ 7
691
;PORT_READ       equ 8
692
;PORT_WRITE      equ 9
693
405 serge 694
 
695
 
413 serge 696
 
697
 
405 serge 698
            dd transmit
699
            dd isr_recieve
700
            dd isr_line
701
702
 
413 serge 703
405 serge 704
 
705
            dw  192,   96,   64,  58,  48,  32
706
            dw   24,   16,   12,   6,   3,   2, 1
707
708
 
709
 
710
 
711