Subversion Repositories Kolibri OS

Rev

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

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