Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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