Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
465 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
 
774 Rus 13
API_VERSION	  equ 0
14
UART_VERSION	  equ API_VERSION
465 serge 15
 
774 Rus 16
PG_SW		  equ 0x003
17
page_tabs	  equ 0xFDC00000     ;hack
465 serge 18
 
774 Rus 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)
465 serge 23
 
24
 
774 Rus 25
struc APPOBJ	       ;common object header
465 serge 26
{
774 Rus 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
465 serge 32
};
33
 
34
virtual at 0
35
  APPOBJ APPOBJ
36
end virtual
37
 
38
struc IOCTL
774 Rus 39
{  .handle	dd ?
40
   .io_code	dd ?
41
   .input	dd ?
42
   .inp_size	dd ?
43
   .output	dd ?
44
   .out_size	dd ?
465 serge 45
}
46
 
47
virtual at 0
48
  IOCTL IOCTL
49
end virtual
50
 
774 Rus 51
DEBUG		 equ   1
465 serge 52
 
774 Rus 53
DRV_ENTRY	 equ   1
54
DRV_EXIT	 equ  -1
465 serge 55
 
774 Rus 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
465 serge 63
 
774 Rus 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
465 serge 75
 
774 Rus 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
465 serge 84
 
774 Rus 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
465 serge 93
 
774 Rus 94
IIR_INTR	 equ  0x01     ;1= no interrupts
465 serge 95
 
774 Rus 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
465 serge 100
 
774 Rus 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
465 serge 106
 
774 Rus 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
465 serge 111
 
112
 
774 Rus 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
465 serge 132
 
774 Rus 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
465 serge 138
 
774 Rus 139
COM_1_BASE	 equ 0x3F8
140
COM_2_BASE	 equ 0x2F8
465 serge 141
 
774 Rus 142
COM_1_IRQ	 equ  4
143
COM_2_IRQ	 equ  3
465 serge 144
 
774 Rus 145
UART_CLOSED	 equ  0
146
UART_TRANSMIT	 equ  1
147
UART_STOP	 equ  2
465 serge 148
 
149
struc UART
150
{
774 Rus 151
   .lock	 dd ?
152
   .base	 dd ?
153
   .lcr_reg	 dd ?
154
   .mcr_reg	 dd ?
155
   .rate	 dd ?
156
   .mode	 dd ?
157
   .state	 dd ?
465 serge 158
 
774 Rus 159
   .rcvr_buff	 dd ?
160
   .rcvr_rp	 dd ?
161
   .rcvr_wp	 dd ?
162
   .rcvr_count	 dd ?
163
   .rcvr_top	 dd ?
465 serge 164
 
774 Rus 165
   .xmit_buff	 dd ?
166
   .xmit_rp	 dd ?
167
   .xmit_wp	 dd ?
168
   .xmit_count	 dd ?
169
   .xmit_free	 dd ?
170
   .xmit_top	 dd ?
465 serge 171
}
172
virtual at 0
173
  UART UART
174
end virtual
175
 
176
UART_SIZE     equ 18*4
177
 
178
struc CONNECTION
179
{
774 Rus 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
465 serge 185
 
774 Rus 186
   .id		dd ?   ;reserved
187
   .uart	dd ?   ;uart pointer
465 serge 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
 
774 Rus 204
	   cmp [state], 1
205
	   jne .stop
465 serge 206
 
774 Rus 207
	   mov eax, UART_SIZE
208
	   call Kmalloc
209
	   test eax, eax
210
	   jz .fail
465 serge 211
 
774 Rus 212
	   mov [com1], eax
213
	   mov edi, eax
214
	   mov ecx, UART_SIZE/4
215
	   xor eax, eax
216
	   cld
217
	   rep stosd
465 serge 218
 
774 Rus 219
	   mov eax, [com1]
220
	   mov [eax+UART.base], COM_1_BASE
465 serge 221
 
774 Rus 222
	   stdcall AllocKernelSpace, 32768
465 serge 223
 
774 Rus 224
	   mov edi, [com1]
225
	   mov edx, eax
465 serge 226
 
774 Rus 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
465 serge 234
 
774 Rus 235
	   call AllocPage
236
	   test eax, eax
237
	   jz .fail
465 serge 238
 
774 Rus 239
	   shr edx, 12
240
	   or eax, PG_SW
241
	   mov [page_tabs+edx*4], eax
242
	   mov [page_tabs+edx*4+8], eax
465 serge 243
 
774 Rus 244
	   call AllocPage
245
	   test eax, eax
246
	   jz .fail
465 serge 247
 
774 Rus 248
	   or eax, PG_SW
249
	   mov [page_tabs+edx*4+4], eax
250
	   mov [page_tabs+edx*4+12], eax
465 serge 251
 
774 Rus 252
	   call AllocPage
253
	   test eax, eax
254
	   jz .fail
465 serge 255
 
774 Rus 256
	   or eax, PG_SW
257
	   mov [page_tabs+edx*4+16], eax
258
	   mov [page_tabs+edx*4+24], eax
465 serge 259
 
774 Rus 260
	   call AllocPage
261
	   test eax, eax
262
	   jz .fail
465 serge 263
 
774 Rus 264
	   or eax, PG_SW
265
	   mov [page_tabs+edx*4+20], eax
266
	   mov [page_tabs+edx*4+28], eax
465 serge 267
 
774 Rus 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]
465 serge 277
 
774 Rus 278
	   mov eax, edi
279
	   call uart_reset.internal   ;eax= uart
465 serge 280
 
774 Rus 281
	   stdcall AttachIntHandler, COM_1_IRQ, com_1_isr, dword 0
282
	   stdcall RegService, sz_uart_srv, service_proc
283
	   ret
465 serge 284
.fail:
285
.stop:
774 Rus 286
	   xor eax, eax
287
	   ret
465 serge 288
endp
289
 
290
 
774 Rus 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
465 serge 297
 
774 Rus 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
465 serge 308
 
309
align 4
310
proc service_proc stdcall, ioctl:dword
311
 
774 Rus 312
	   mov ebx, [ioctl]
313
	   mov eax, [ebx+io_code]
314
	   cmp eax, PORT_WRITE
315
	   ja .fail
465 serge 316
 
774 Rus 317
	   cmp eax, SRV_GETVERSION
318
	   jne @F
465 serge 319
 
774 Rus 320
	   mov eax, [ebx+output]
321
	   cmp [ebx+out_size], 4
322
	   jne .fail
323
	   mov [eax], dword UART_VERSION
324
	   xor eax, eax
325
	   ret
465 serge 326
@@:
774 Rus 327
	   cmp eax, PORT_OPEN
328
	   jne @F
465 serge 329
 
774 Rus 330
	   cmp [ebx+out_size], 4
331
	   jne .fail
465 serge 332
 
774 Rus 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
465 serge 340
@@:
774 Rus 341
	   mov esi, [ebx+input]     ;input buffer
342
	   mov edi, [ebx+output]
343
	   call [uart_func+eax*4]
344
	   ret
465 serge 345
.fail:
774 Rus 346
	   or eax, -1
347
	   ret
465 serge 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:
774 Rus 368
	   mov eax, [esi]
369
	   cmp [eax+APPOBJ.magic], 'CNCT'
370
	   jne .fail
465 serge 371
 
774 Rus 372
	   cmp [eax+APPOBJ.destroy], uart_close.destroy
373
	   jne .fail
465 serge 374
 
774 Rus 375
	   mov eax, [eax+CONNECTION.uart]
376
	   test eax, eax
377
	   jz .fail
465 serge 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:
774 Rus 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
465 serge 395
 
774 Rus 396
	   mov eax, esi
397
	   mov ebx, RATE_2400
398
	   mov ecx, LCR_8BIT+LCR_STOP_1
399
	   call uart_set_mode.internal
465 serge 400
 
774 Rus 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
465 serge 405
.clear_RB:
774 Rus 406
	   mov edx, [esi+UART.base]
407
	   add edx, LSR_REG
408
	   in al, dx
409
	   test eax, LSR_DR
410
	   jz @F
465 serge 411
 
774 Rus 412
	   mov edx, [esi+UART.base]
413
	   in al, dx
414
	   jmp .clear_RB
465 serge 415
@@:
774 Rus 416
	   mov edx, [esi+UART.base]
417
	   add edx, IER_REG
418
	   mov eax,IER_RDAI+IER_THRI+IER_LSI
419
	   out dx, al
465 serge 420
.clear_IIR:
774 Rus 421
	   mov edx, [esi+UART.base]
422
	   add edx, IIR_REG
423
	   in al, dx
424
	   test al, IIR_INTR
425
	   jnz .done
465 serge 426
 
774 Rus 427
	   shr eax, 1
428
	   and eax, 3
429
	   jnz @F
465 serge 430
 
774 Rus 431
	   mov edx, [esi+UART.base]
432
	   add edx, MSR_REG
433
	   in al, dx
434
	   jmp .clear_IIR
465 serge 435
@@:
774 Rus 436
	   cmp eax, 1
437
	   je .clear_IIR
465 serge 438
 
774 Rus 439
	   cmp eax, 2
440
	   jne @F
465 serge 441
 
774 Rus 442
	   mov edx, [esi+UART.base]
443
	   in al, dx
444
	   jmp .clear_IIR
465 serge 445
@@:
774 Rus 446
	   mov edx, [esi+UART.base]
447
	   add edx, LSR_REG
448
	   in al, dx
449
	   jmp .clear_IIR
465 serge 450
.done:
774 Rus 451
	   mov edi, [esi+UART.rcvr_buff]
452
	   mov ecx, 8192/4
453
	   xor eax, eax
465 serge 454
 
774 Rus 455
	   mov [esi+UART.rcvr_rp], edi
456
	   mov [esi+UART.rcvr_wp], edi
457
	   mov [esi+UART.rcvr_count], eax
465 serge 458
 
774 Rus 459
	   cld
460
	   rep stosd
465 serge 461
 
774 Rus 462
	   mov edi, [esi+UART.xmit_buff]
463
	   mov ecx, 8192/4
465 serge 464
 
774 Rus 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
465 serge 469
 
774 Rus 470
	   rep stosd
471
	   ret		     ;eax= 0
465 serge 472
.fail:
774 Rus 473
	   or eax, -1
474
	   ret
465 serge 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:
774 Rus 487
	   mov eax, [esi]
488
	   cmp [eax+APPOBJ.magic], 'CNCT'
489
	   jne .fail
465 serge 490
 
774 Rus 491
	   cmp [eax+APPOBJ.destroy], uart_close.destroy
492
	   jne .fail
465 serge 493
 
774 Rus 494
	   mov eax, [eax+CONNECTION.uart]
495
	   test eax, eax
496
	   jz .fail
465 serge 497
 
774 Rus 498
	   mov ebx, [esi+4]
499
	   mov ecx, [esi+8]
465 serge 500
 
501
; param
502
;  eax= uart
503
;  ebx= baud rate
504
;  ecx= mode
505
 
506
align 4
507
.internal:
774 Rus 508
	   cmp ebx, RATE_115200
509
	   ja .fail
465 serge 510
 
774 Rus 511
	   cmp ecx, LCR_BREAK
512
	   jae .fail
465 serge 513
 
774 Rus 514
	   mov [eax+UART.rate], ebx
515
	   mov [eax+UART.mode], ecx
465 serge 516
 
774 Rus 517
	   mov esi, eax
518
	   mov bx, [divisor+ebx*2]
465 serge 519
 
774 Rus 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
465 serge 526
 
774 Rus 527
	   pop edx
528
	   mov al, bl
529
	   out dx, al
465 serge 530
 
774 Rus 531
	   inc dx
532
	   mov al, bh
533
	   out dx, al
465 serge 534
 
774 Rus 535
	   add edx, LCR_REG-1
536
	   mov eax, ecx
537
	   out dx, al
538
	   xor eax, eax
539
	   ret
465 serge 540
.fail:
774 Rus 541
	   or eax, -1
542
	   ret
465 serge 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
 
774 Rus 555
	   mov eax, [esi]
556
	   cmp [eax+APPOBJ.magic], 'CNCT'
557
	   jne .fail
465 serge 558
 
774 Rus 559
	   cmp [eax+APPOBJ.destroy], uart_close.destroy
560
	   jne .fail
465 serge 561
 
774 Rus 562
	   mov eax, [eax+CONNECTION.uart]
563
	   test eax, eax
564
	   jz .fail
465 serge 565
 
774 Rus 566
	   mov ebx, [esi+4]
465 serge 567
 
774 Rus 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
465 serge 575
.fail:
774 Rus 576
	   or eax, -1
577
	   ret
465 serge 578
 
579
; param
580
;  eax= port
581
;
582
; retval
583
;  ecx= connection
584
;  eax= error code
585
 
586
align 4
587
uart_open:
774 Rus 588
	   dec eax
589
	   cmp eax, COM_MAX
590
	   jae .fail
465 serge 591
 
774 Rus 592
	   mov esi, [com1+eax*4]	     ;uart
593
	   push esi
465 serge 594
.do_wait:
774 Rus 595
	   cmp dword [esi+UART.lock],0
596
	   je .get_lock
465 serge 597
      ;     call change_task
774 Rus 598
	   jmp .do_wait
465 serge 599
.get_lock:
774 Rus 600
	   mov eax, 1
601
	   xchg eax, [esi+UART.lock]
602
	   test eax, eax
603
	   jnz .do_wait
465 serge 604
 
774 Rus 605
	   mov eax, esi 		 ;uart
606
	   call uart_reset.internal
465 serge 607
 
774 Rus 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
465 serge 616
 
774 Rus 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
465 serge 623
.fail:
774 Rus 624
	   or eax, -1
625
	   ret
465 serge 626
restore .uart
627
 
628
; param
629
;  esi= input buffer
630
 
631
align 4
632
uart_close:
774 Rus 633
	   mov eax, [esi]
634
	   cmp [eax+APPOBJ.magic], 'CNCT'
635
	   jne .fail
465 serge 636
 
774 Rus 637
	   cmp [eax+APPOBJ.destroy], uart_close.destroy
638
	   jne .fail
465 serge 639
.destroy:
774 Rus 640
	   push [eax+CONNECTION.uart]
641
	   call DestroyObject	;eax= object
642
	   pop eax			;eax= uart
643
	   test eax, eax
644
	   jz .fail
465 serge 645
 
774 Rus 646
	   mov [eax+UART.state], UART_CLOSED
647
	   mov [eax+UART.lock], 0 ;release port
648
	   xor eax, eax
649
	   ret
465 serge 650
.fail:
774 Rus 651
	   or eax, -1
652
	   ret
465 serge 653
 
654
 
655
; param
656
;  eax= uart
657
;  ebx= baud rate
658
 
659
align 4
660
set_rate:
774 Rus 661
	   cmp ebx, RATE_115200
662
	   ja .fail
465 serge 663
 
774 Rus 664
	   mov [eax+UART.rate], ebx
665
	   mov bx, [divisor+ebx*2]
465 serge 666
 
774 Rus 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
465 serge 673
 
774 Rus 674
	   sub edx, LCR_REG
675
	   mov al, bl
676
	   out dx, al
465 serge 677
 
774 Rus 678
	   inc edx
679
	   mov al, bh
680
	   out dx, al
465 serge 681
 
774 Rus 682
	   pop eax
683
	   add edx, LCR_REG-1
684
	   out dx, al
465 serge 685
.fail:
774 Rus 686
	   ret
465 serge 687
 
688
 
689
; param
690
;   ebx= uart
691
 
692
align 4
693
transmit:
774 Rus 694
	   push esi
695
	   push edi
465 serge 696
 
774 Rus 697
	   mov edx, [ebx+UART.base]
465 serge 698
 
774 Rus 699
	   pushfd
700
	   cli
465 serge 701
 
774 Rus 702
	   mov esi, [ebx+UART.xmit_rp]
703
	   mov ecx, [ebx+UART.xmit_count]
704
	   test ecx, ecx
705
	   je .stop
465 serge 706
 
774 Rus 707
	   cmp ecx, 16
708
	   jbe @F
709
	   mov ecx, 16
465 serge 710
@@:
774 Rus 711
	   sub [ebx+UART.xmit_count], ecx
712
	   add [ebx+UART.xmit_free], ecx
713
	   cld
465 serge 714
@@:
774 Rus 715
	   lodsb
716
	   out dx, al
717
	   dec ecx
718
	   jnz @B
465 serge 719
 
774 Rus 720
	   cmp esi,[ebx+UART.xmit_top]
721
	   jb @F
722
	   sub esi, 8192
465 serge 723
@@:
774 Rus 724
	   mov [ebx+UART.xmit_rp], esi
465 serge 725
 
774 Rus 726
	   cmp [ebx+UART.xmit_count], 0
727
	   je .stop
465 serge 728
 
774 Rus 729
	   mov [ebx+UART.state], UART_TRANSMIT
730
	   jmp @F
465 serge 731
.stop:
774 Rus 732
	   mov [ebx+UART.state], UART_STOP
465 serge 733
@@:
774 Rus 734
	   popfd
735
	   pop edi
736
	   pop esi
737
	   ret
465 serge 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:
774 Rus 753
	   mov eax, [esi]
754
	   cmp [eax+APPOBJ.magic], 'CNCT'
755
	   jne .fail
465 serge 756
 
774 Rus 757
	   cmp [eax+APPOBJ.destroy], uart_close.destroy
758
	   jne .fail
465 serge 759
 
774 Rus 760
	   mov eax, [eax+CONNECTION.uart]
761
	   test eax, eax
762
	   jz .fail
465 serge 763
 
774 Rus 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
465 serge 769
@@:
774 Rus 770
	   mov [edi], ecx      ;bytes read
771
	   test ecx, ecx
772
	   jz .done
465 serge 773
 
774 Rus 774
	   push ecx
465 serge 775
 
774 Rus 776
	   mov edi, [esi+4]    ;dst
777
	   mov esi, [eax+UART.rcvr_rp]
778
	   cld
779
	   rep movsb
780
	   pop ecx
465 serge 781
 
774 Rus 782
	   cmp esi, [eax+UART.rcvr_top]
783
	   jb @F
784
	   sub esi, 8192
465 serge 785
@@:
774 Rus 786
	   mov [eax+UART.rcvr_rp], esi
787
	   sub [eax+UART.rcvr_count], ecx
465 serge 788
.done:
774 Rus 789
	   xor eax, eax
790
	   ret
465 serge 791
.fail:
774 Rus 792
	   or eax, -1
793
	   ret
465 serge 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:
774 Rus 806
	   mov eax, [esi]
807
	   cmp [eax+APPOBJ.magic], 'CNCT'
808
	   jne .fail
465 serge 809
 
774 Rus 810
	   cmp [eax+APPOBJ.destroy], uart_close.destroy
811
	   jne .fail
465 serge 812
 
774 Rus 813
	   mov eax, [eax+CONNECTION.uart]
814
	   test eax, eax
815
	   jz .fail
465 serge 816
 
774 Rus 817
	   mov ebx, [esi+4]
818
	   mov edx, [esi+8]
465 serge 819
 
820
; param
821
;  eax= uart
822
;  ebx= src
823
;  edx= count
824
 
825
align 4
826
.internal:
774 Rus 827
	   mov esi, ebx
828
	   mov edi, [eax+UART.xmit_wp]
465 serge 829
.write:
774 Rus 830
	   test edx, edx
831
	   jz .fail
465 serge 832
.wait:
774 Rus 833
	   cmp [eax+UART.xmit_free], 0
834
	   jne .fill
465 serge 835
 
774 Rus 836
	   cmp [eax+UART.state], UART_TRANSMIT
837
	   je .wait
465 serge 838
 
774 Rus 839
	   mov ebx, eax
840
	   push edx
841
	   call transmit
842
	   pop edx
843
	   mov eax, ebx
844
	   jmp .write
465 serge 845
.fill:
774 Rus 846
	   mov ecx, [eax+UART.xmit_free]
847
	   cmp ecx, edx
848
	   jbe @F
849
	   mov ecx, edx
465 serge 850
@@:
774 Rus 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
465 serge 859
.done:
774 Rus 860
	   cmp edi, [eax+UART.xmit_top]
861
	   jb @F
862
	   sub edi, 8192
465 serge 863
@@:
774 Rus 864
	   mov [eax+UART.xmit_wp], edi
865
	   cmp [eax+UART.state], UART_TRANSMIT
866
	   je @F
867
	   mov ebx, eax
868
	   call transmit
465 serge 869
@@:
774 Rus 870
	   xor eax, eax
871
	   ret
465 serge 872
.fail:
774 Rus 873
	   or eax, -1
874
	   ret
465 serge 875
 
876
 
877
align 4
878
com_2_isr:
774 Rus 879
	   mov ebx, [com2]
880
	   jmp com_1_isr.get_info
465 serge 881
align 4
882
com_1_isr:
774 Rus 883
	   mov ebx, [com1]
465 serge 884
.get_info:
774 Rus 885
	   mov edx, [ebx+UART.base]
886
	   add edx, IIR_REG
887
	   in  al, dx
465 serge 888
 
774 Rus 889
	   test al, IIR_INTR
890
	   jnz .done
465 serge 891
 
774 Rus 892
	   shr eax, 1
893
	   and eax, 3
465 serge 894
 
774 Rus 895
	   call [isr_action+eax*4]
896
	   jmp .get_info
465 serge 897
.done:
774 Rus 898
	   ret
465 serge 899
 
900
align 4
901
isr_line:
774 Rus 902
	   mov edx, [ebx+UART.base]
903
	   add edx, LSR_REG
904
	   in al, dx
905
	   ret
465 serge 906
 
907
align 4
908
isr_recieve:
774 Rus 909
	   mov esi, [ebx+UART.base]
910
	   add esi, LSR_REG
911
	   mov edi, [ebx+UART.rcvr_wp]
912
	   xor ecx, ecx
913
	   cld
465 serge 914
.read:
774 Rus 915
	   mov edx, esi
916
	   in al, dx
917
	   test eax, LSR_DR
918
	   jz .done
465 serge 919
 
774 Rus 920
	   mov edx, [ebx+UART.base]
921
	   in al, dx
922
	   stosb
923
	   inc ecx
924
	   jmp .read
465 serge 925
.done:
774 Rus 926
	   cmp edi, [ebx+UART.rcvr_top]
927
	   jb @F
928
	   sub edi, 8192
465 serge 929
@@:
774 Rus 930
	   mov [ebx+UART.rcvr_wp], edi
931
	   add [ebx+UART.rcvr_count], ecx
932
	   ret
465 serge 933
 
934
align 4
935
isr_modem:
774 Rus 936
	   mov edx, [ebx+UART.base]
937
	   add edx, MSR_REG
938
	   in al, dx
939
	   ret
465 serge 940
 
941
 
942
align 4
943
divisor    dw 2304, 1536, 1047, 857, 768, 384
774 Rus 944
	   dw  192,   96,   64,  58,  48,  32
945
	   dw	24,   16,   12,   6,   3,   2, 1
465 serge 946
 
947
align 4
774 Rus 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
465 serge 958
 
959
isr_action  dd isr_modem
774 Rus 960
	    dd transmit
961
	    dd isr_recieve
962
	    dd isr_line
465 serge 963
 
964
version     dd (5 shl 16) or (UART_VERSION and 0xFFFF)
965
 
966
sz_uart_srv db 'UART',0
967
 
968
align 4
969
 
774 Rus 970
com1	    rd 1
971
com2	    rd 1
465 serge 972