Subversion Repositories Kolibri OS

Rev

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