Subversion Repositories Kolibri OS

Rev

Rev 5363 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. format PE DLL native 0.05
  9. entry START
  10.  
  11. __DEBUG__       equ 1
  12. __DEBUG_LEVEL__ equ 1  ; 1 = verbose, 2 = errors only
  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.  
  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.  
  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
  42. }
  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
  97. MCR_LOOP         equ  0x10     ;loopback mode
  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. }
  164.  
  165. virtual at 0
  166.   UART UART
  167. end virtual
  168.  
  169. UART_SIZE    equ 18*4
  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.  
  190. ;proc START c, state:dword
  191. ;       cmp     [state], 1
  192.  
  193. align 4
  194. proc START c, state:dword
  195.         DEBUGF  1, "Loading driver UART (entry at %x)...\n", START
  196.  
  197.         push    esi                   ; [bw] ???
  198.         cmp     [state], DRV_ENTRY
  199.         jne     .stop
  200.  
  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
  209.         test    eax, eax
  210.         jz      .fail
  211.  
  212.         DEBUGF  1, "Structure %x allocated\n", eax
  213.  
  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.  
  224.         invoke  AllocKernelSpace, 32768
  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.  
  237.         invoke  AllocPage
  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.  
  246.         invoke  AllocPage
  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.  
  254.         invoke  AllocPage
  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.  
  262.         invoke  AllocPage
  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.  
  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
  293.         ret
  294.  
  295. .fail:
  296. .stop:
  297.         DEBUGF  2, "Failed\n"
  298.         pop     esi
  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.  
  362. ;restore   handle
  363. ;restore   io_code
  364. ;restore   input
  365. ;restore   inp_size
  366. ;restore   output
  367. ;restore   out_size
  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
  408. ;       mov     ebx, RATE_2400
  409.         mov     ebx, RATE_115200
  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.  
  604.         mov     esi, [com1+eax*4]        ;uart
  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
  624.         invoke  CreateObject
  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
  651.  
  652. .destroy:
  653. ;       DEBUGF 1, "[UART.destroy] eax=%x uart=%x\n", eax, [eax+CONNECTION.uart]
  654.         push    [eax+CONNECTION.uart]
  655.         invoke  DestroyObject            ;eax= object
  656.         pop     eax                      ;eax= uart
  657.         test    eax, eax
  658.         jz      .fail
  659.  
  660.         mov     [eax+UART.state], UART_CLOSED
  661.         mov     [eax+UART.lock], 0       ;release port
  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
  895.  
  896. align 4
  897. com_1_isr:
  898.         mov     ebx, [com1]
  899.  
  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:
  925. ;       DEBUGF 1, "[UART.isr_recieve] ebx=%x\n", ebx
  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.  
  983. sz_uart_srv db 'UART', 0
  984. msg_start   db 'Loading UART driver...',13,10,0
  985.  
  986. include_debug_strings  ; All data wich FDO uses will be included here
  987.  
  988. align 4
  989. com1        rd 1
  990. com2        rd 1
  991.  
  992. align 4
  993. data fixups
  994. end data
  995.