forked from KolibriOS/kolibrios
move incomplete uart.asm into /drivers/old
git-svn-id: svn://kolibrios.org@5079 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
976
drivers/old/uart.asm
Normal file
976
drivers/old/uart.asm
Normal file
@@ -0,0 +1,976 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
format MS COFF
|
||||
|
||||
DEBUG equ 1
|
||||
|
||||
include 'proc32.inc'
|
||||
include 'imports.inc'
|
||||
|
||||
|
||||
|
||||
API_VERSION equ 0
|
||||
UART_VERSION equ API_VERSION
|
||||
|
||||
PG_SW equ 0x003
|
||||
page_tabs equ 0xFDC00000 ;hack
|
||||
|
||||
OS_BASE equ 0x80000000
|
||||
SLOT_BASE equ (OS_BASE+0x0080000)
|
||||
TASK_COUNT equ (OS_BASE+0x0003004)
|
||||
CURRENT_TASK equ (OS_BASE+0x0003000)
|
||||
|
||||
|
||||
struc APPOBJ ;common object header
|
||||
{
|
||||
.magic dd ? ;
|
||||
.destroy dd ? ;internal destructor
|
||||
.fd dd ? ;next object in list
|
||||
.bk dd ? ;prev object in list
|
||||
.pid dd ? ;owner id
|
||||
};
|
||||
|
||||
virtual at 0
|
||||
APPOBJ APPOBJ
|
||||
end virtual
|
||||
|
||||
struc IOCTL
|
||||
{ .handle dd ?
|
||||
.io_code dd ?
|
||||
.input dd ?
|
||||
.inp_size dd ?
|
||||
.output dd ?
|
||||
.out_size dd ?
|
||||
}
|
||||
|
||||
virtual at 0
|
||||
IOCTL IOCTL
|
||||
end virtual
|
||||
|
||||
DEBUG equ 1
|
||||
|
||||
DRV_ENTRY equ 1
|
||||
DRV_EXIT equ -1
|
||||
|
||||
THR_REG equ 0; x3f8 ;transtitter/reciever
|
||||
IER_REG equ 1; x3f9 ;interrupt enable
|
||||
IIR_REG equ 2; x3fA ;interrupt info
|
||||
LCR_REG equ 3; x3FB ;line control
|
||||
MCR_REG equ 4; x3FC ;modem control
|
||||
LSR_REG equ 5; x3FD ;line status
|
||||
MSR_REG equ 6; x3FE ;modem status
|
||||
|
||||
LCR_5BIT equ 0x00
|
||||
LCR_6BIT equ 0x01
|
||||
LCR_7BIT equ 0x02
|
||||
LCR_8BIT equ 0x03
|
||||
LCR_STOP_1 equ 0x00
|
||||
LCR_STOP_2 equ 0x04
|
||||
LCR_PARITY equ 0x08
|
||||
LCR_EVEN equ 0x10
|
||||
LCR_STICK equ 0x20
|
||||
LCR_BREAK equ 0x40
|
||||
LCR_DLAB equ 0x80
|
||||
|
||||
LSR_DR equ 0x01 ;data ready
|
||||
LSR_OE equ 0x02 ;overrun error
|
||||
LSR_PE equ 0x04 ;parity error
|
||||
LSR_FE equ 0x08 ;framing error
|
||||
LSR_BI equ 0x10 ;break interrupt
|
||||
LSR_THRE equ 0x20 ;transmitter holding empty
|
||||
LSR_TEMT equ 0x40 ;transmitter empty
|
||||
LSR_FER equ 0x80 ;FIFO error
|
||||
|
||||
FCR_EFIFO equ 0x01 ;enable FIFO
|
||||
FCR_CRB equ 0x02 ;clear reciever FIFO
|
||||
FCR_CXMIT equ 0x04 ;clear transmitter FIFO
|
||||
FCR_RDY equ 0x08 ;set RXRDY and TXRDY pins
|
||||
FCR_FIFO_1 equ 0x00 ;1 byte trigger
|
||||
FCR_FIFO_4 equ 0x40 ;4 bytes trigger
|
||||
FCR_FIFO_8 equ 0x80 ;8 bytes trigger
|
||||
FCR_FIFO_14 equ 0xC0 ;14 bytes trigger
|
||||
|
||||
IIR_INTR equ 0x01 ;1= no interrupts
|
||||
|
||||
IER_RDAI equ 0x01 ;reciever data interrupt
|
||||
IER_THRI equ 0x02 ;transmitter empty interrupt
|
||||
IER_LSI equ 0x04 ;line status interrupt
|
||||
IER_MSI equ 0x08 ;modem status interrupt
|
||||
|
||||
MCR_DTR equ 0x01 ;0-> DTR=1, 1-> DTR=0
|
||||
MCR_RTS equ 0x02 ;0-> RTS=1, 1-> RTS=0
|
||||
MCR_OUT_1 equ 0x04 ;0-> OUT1=1, 1-> OUT1=0
|
||||
MCR_OUT_2 equ 0x08 ;0-> OUT2=1, 1-> OUT2=0; enable intr
|
||||
MCR_LOOP equ 0x10 ;lopback mode
|
||||
|
||||
MSR_DCTS equ 0x01 ;delta clear to send
|
||||
MSR_DDSR equ 0x02 ;delta data set redy
|
||||
MSR_TERI equ 0x04 ;trailinh edge of ring
|
||||
MSR_DDCD equ 0x08 ;delta carrier detect
|
||||
|
||||
|
||||
RATE_50 equ 0
|
||||
RATE_75 equ 1
|
||||
RATE_110 equ 2
|
||||
RATE_134 equ 3
|
||||
RATE_150 equ 4
|
||||
RATE_300 equ 5
|
||||
RATE_600 equ 6
|
||||
RATE_1200 equ 7
|
||||
RATE_1800 equ 8
|
||||
RATE_2000 equ 9
|
||||
RATE_2400 equ 10
|
||||
RATE_3600 equ 11
|
||||
RATE_4800 equ 12
|
||||
RATE_7200 equ 13
|
||||
RATE_9600 equ 14
|
||||
RATE_19200 equ 15
|
||||
RATE_38400 equ 16
|
||||
RATE_57600 equ 17
|
||||
RATE_115200 equ 18
|
||||
|
||||
COM_1 equ 1
|
||||
COM_2 equ 2
|
||||
COM_3 equ 3
|
||||
COM_4 equ 4
|
||||
COM_MAX equ 2 ;only two port supported
|
||||
|
||||
COM_1_BASE equ 0x3F8
|
||||
COM_2_BASE equ 0x2F8
|
||||
|
||||
COM_1_IRQ equ 4
|
||||
COM_2_IRQ equ 3
|
||||
|
||||
UART_CLOSED equ 0
|
||||
UART_TRANSMIT equ 1
|
||||
UART_STOP equ 2
|
||||
|
||||
struc UART
|
||||
{
|
||||
.lock dd ?
|
||||
.base dd ?
|
||||
.lcr_reg dd ?
|
||||
.mcr_reg dd ?
|
||||
.rate dd ?
|
||||
.mode dd ?
|
||||
.state dd ?
|
||||
|
||||
.rcvr_buff dd ?
|
||||
.rcvr_rp dd ?
|
||||
.rcvr_wp dd ?
|
||||
.rcvr_count dd ?
|
||||
.rcvr_top dd ?
|
||||
|
||||
.xmit_buff dd ?
|
||||
.xmit_rp dd ?
|
||||
.xmit_wp dd ?
|
||||
.xmit_count dd ?
|
||||
.xmit_free dd ?
|
||||
.xmit_top dd ?
|
||||
}
|
||||
virtual at 0
|
||||
UART UART
|
||||
end virtual
|
||||
|
||||
UART_SIZE equ 18*4
|
||||
|
||||
struc CONNECTION
|
||||
{
|
||||
.magic dd ? ;'CNCT'
|
||||
.destroy dd ? ;internal destructor
|
||||
.fd dd ? ;next object in list
|
||||
.bk dd ? ;prev object in list
|
||||
.pid dd ? ;owner id
|
||||
|
||||
.id dd ? ;reserved
|
||||
.uart dd ? ;uart pointer
|
||||
}
|
||||
|
||||
virtual at 0
|
||||
CONNECTION CONNECTION
|
||||
end virtual
|
||||
|
||||
CONNECTION_SIZE equ 7*4
|
||||
|
||||
public START
|
||||
public service_proc
|
||||
public version
|
||||
|
||||
section '.flat' code readable align 16
|
||||
|
||||
proc START stdcall, state:dword
|
||||
|
||||
cmp [state], 1
|
||||
jne .stop
|
||||
|
||||
mov eax, UART_SIZE
|
||||
call Kmalloc
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
mov [com1], eax
|
||||
mov edi, eax
|
||||
mov ecx, UART_SIZE/4
|
||||
xor eax, eax
|
||||
cld
|
||||
rep stosd
|
||||
|
||||
mov eax, [com1]
|
||||
mov [eax+UART.base], COM_1_BASE
|
||||
|
||||
stdcall AllocKernelSpace, 32768
|
||||
|
||||
mov edi, [com1]
|
||||
mov edx, eax
|
||||
|
||||
mov [edi+UART.rcvr_buff], eax
|
||||
add eax, 8192
|
||||
mov [edi+UART.rcvr_top], eax
|
||||
add eax, 8192
|
||||
mov [edi+UART.xmit_buff], eax
|
||||
add eax, 8192
|
||||
mov [edi+UART.xmit_top], eax
|
||||
|
||||
call AllocPage
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
shr edx, 12
|
||||
or eax, PG_SW
|
||||
mov [page_tabs+edx*4], eax
|
||||
mov [page_tabs+edx*4+8], eax
|
||||
|
||||
call AllocPage
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
or eax, PG_SW
|
||||
mov [page_tabs+edx*4+4], eax
|
||||
mov [page_tabs+edx*4+12], eax
|
||||
|
||||
call AllocPage
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
or eax, PG_SW
|
||||
mov [page_tabs+edx*4+16], eax
|
||||
mov [page_tabs+edx*4+24], eax
|
||||
|
||||
call AllocPage
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
or eax, PG_SW
|
||||
mov [page_tabs+edx*4+20], eax
|
||||
mov [page_tabs+edx*4+28], eax
|
||||
|
||||
mov eax, [edi+UART.rcvr_buff]
|
||||
invlpg [eax]
|
||||
invlpg [eax+0x1000]
|
||||
invlpg [eax+0x2000]
|
||||
invlpg [eax+0x3000]
|
||||
invlpg [eax+0x4000]
|
||||
invlpg [eax+0x5000]
|
||||
invlpg [eax+0x6000]
|
||||
invlpg [eax+0x7000]
|
||||
|
||||
mov eax, edi
|
||||
call uart_reset.internal ;eax= uart
|
||||
|
||||
stdcall AttachIntHandler, COM_1_IRQ, com_1_isr, dword 0
|
||||
stdcall RegService, sz_uart_srv, service_proc
|
||||
ret
|
||||
.fail:
|
||||
.stop:
|
||||
xor eax, eax
|
||||
ret
|
||||
endp
|
||||
|
||||
|
||||
handle equ IOCTL.handle
|
||||
io_code equ IOCTL.io_code
|
||||
input equ IOCTL.input
|
||||
inp_size equ IOCTL.inp_size
|
||||
output equ IOCTL.output
|
||||
out_size equ IOCTL.out_size
|
||||
|
||||
SRV_GETVERSION equ 0
|
||||
PORT_OPEN equ 1
|
||||
PORT_CLOSE equ 2
|
||||
PORT_RESET equ 3
|
||||
PORT_SETMODE equ 4
|
||||
PORT_GETMODE equ 5
|
||||
PORT_SETMCR equ 6
|
||||
PORT_GETMCR equ 7
|
||||
PORT_READ equ 8
|
||||
PORT_WRITE equ 9
|
||||
|
||||
align 4
|
||||
proc service_proc stdcall, ioctl:dword
|
||||
|
||||
mov ebx, [ioctl]
|
||||
mov eax, [ebx+io_code]
|
||||
cmp eax, PORT_WRITE
|
||||
ja .fail
|
||||
|
||||
cmp eax, SRV_GETVERSION
|
||||
jne @F
|
||||
|
||||
mov eax, [ebx+output]
|
||||
cmp [ebx+out_size], 4
|
||||
jne .fail
|
||||
mov [eax], dword UART_VERSION
|
||||
xor eax, eax
|
||||
ret
|
||||
@@:
|
||||
cmp eax, PORT_OPEN
|
||||
jne @F
|
||||
|
||||
cmp [ebx+out_size], 4
|
||||
jne .fail
|
||||
|
||||
mov ebx, [ebx+input]
|
||||
mov eax, [ebx]
|
||||
call uart_open
|
||||
mov ebx, [ioctl]
|
||||
mov ebx, [ebx+output]
|
||||
mov [ebx], ecx
|
||||
ret
|
||||
@@:
|
||||
mov esi, [ebx+input] ;input buffer
|
||||
mov edi, [ebx+output]
|
||||
call [uart_func+eax*4]
|
||||
ret
|
||||
.fail:
|
||||
or eax, -1
|
||||
ret
|
||||
|
||||
endp
|
||||
|
||||
restore handle
|
||||
restore io_code
|
||||
restore input
|
||||
restore inp_size
|
||||
restore output
|
||||
restore out_size
|
||||
|
||||
|
||||
; param
|
||||
; esi= input buffer
|
||||
; +0 connection
|
||||
;
|
||||
; retval
|
||||
; eax= error code
|
||||
|
||||
align 4
|
||||
uart_reset:
|
||||
mov eax, [esi]
|
||||
cmp [eax+APPOBJ.magic], 'CNCT'
|
||||
jne .fail
|
||||
|
||||
cmp [eax+APPOBJ.destroy], uart_close.destroy
|
||||
jne .fail
|
||||
|
||||
mov eax, [eax+CONNECTION.uart]
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
; set mode 2400 bod 8-bit
|
||||
; disable DTR & RTS
|
||||
; clear FIFO
|
||||
; clear pending interrupts
|
||||
;
|
||||
; param
|
||||
; eax= uart
|
||||
|
||||
align 4
|
||||
.internal:
|
||||
mov esi, eax
|
||||
mov [eax+UART.state], UART_CLOSED
|
||||
mov edx, [eax+UART.base]
|
||||
add edx, MCR_REG
|
||||
xor eax, eax
|
||||
out dx, al ;clear DTR & RTS
|
||||
|
||||
mov eax, esi
|
||||
mov ebx, RATE_2400
|
||||
mov ecx, LCR_8BIT+LCR_STOP_1
|
||||
call uart_set_mode.internal
|
||||
|
||||
mov edx, [esi+UART.base]
|
||||
add edx, IIR_REG
|
||||
mov eax, FCR_EFIFO+FCR_CRB+FCR_CXMIT+FCR_FIFO_14
|
||||
out dx, al
|
||||
.clear_RB:
|
||||
mov edx, [esi+UART.base]
|
||||
add edx, LSR_REG
|
||||
in al, dx
|
||||
test eax, LSR_DR
|
||||
jz @F
|
||||
|
||||
mov edx, [esi+UART.base]
|
||||
in al, dx
|
||||
jmp .clear_RB
|
||||
@@:
|
||||
mov edx, [esi+UART.base]
|
||||
add edx, IER_REG
|
||||
mov eax, IER_RDAI+IER_THRI+IER_LSI
|
||||
out dx, al
|
||||
.clear_IIR:
|
||||
mov edx, [esi+UART.base]
|
||||
add edx, IIR_REG
|
||||
in al, dx
|
||||
test al, IIR_INTR
|
||||
jnz .done
|
||||
|
||||
shr eax, 1
|
||||
and eax, 3
|
||||
jnz @F
|
||||
|
||||
mov edx, [esi+UART.base]
|
||||
add edx, MSR_REG
|
||||
in al, dx
|
||||
jmp .clear_IIR
|
||||
@@:
|
||||
cmp eax, 1
|
||||
je .clear_IIR
|
||||
|
||||
cmp eax, 2
|
||||
jne @F
|
||||
|
||||
mov edx, [esi+UART.base]
|
||||
in al, dx
|
||||
jmp .clear_IIR
|
||||
@@:
|
||||
mov edx, [esi+UART.base]
|
||||
add edx, LSR_REG
|
||||
in al, dx
|
||||
jmp .clear_IIR
|
||||
.done:
|
||||
mov edi, [esi+UART.rcvr_buff]
|
||||
mov ecx, 8192/4
|
||||
xor eax, eax
|
||||
|
||||
mov [esi+UART.rcvr_rp], edi
|
||||
mov [esi+UART.rcvr_wp], edi
|
||||
mov [esi+UART.rcvr_count], eax
|
||||
|
||||
cld
|
||||
rep stosd
|
||||
|
||||
mov edi, [esi+UART.xmit_buff]
|
||||
mov ecx, 8192/4
|
||||
|
||||
mov [esi+UART.xmit_rp], edi
|
||||
mov [esi+UART.xmit_wp], edi
|
||||
mov [esi+UART.xmit_count], eax
|
||||
mov [esi+UART.xmit_free], 8192
|
||||
|
||||
rep stosd
|
||||
ret ;eax= 0
|
||||
.fail:
|
||||
or eax, -1
|
||||
ret
|
||||
|
||||
; param
|
||||
; esi= input buffer
|
||||
; +0 connection
|
||||
; +4 rate
|
||||
; +8 mode
|
||||
;
|
||||
; retval
|
||||
; eax= error code
|
||||
|
||||
align 4
|
||||
uart_set_mode:
|
||||
mov eax, [esi]
|
||||
cmp [eax+APPOBJ.magic], 'CNCT'
|
||||
jne .fail
|
||||
|
||||
cmp [eax+APPOBJ.destroy], uart_close.destroy
|
||||
jne .fail
|
||||
|
||||
mov eax, [eax+CONNECTION.uart]
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
mov ebx, [esi+4]
|
||||
mov ecx, [esi+8]
|
||||
|
||||
; param
|
||||
; eax= uart
|
||||
; ebx= baud rate
|
||||
; ecx= mode
|
||||
|
||||
align 4
|
||||
.internal:
|
||||
cmp ebx, RATE_115200
|
||||
ja .fail
|
||||
|
||||
cmp ecx, LCR_BREAK
|
||||
jae .fail
|
||||
|
||||
mov [eax+UART.rate], ebx
|
||||
mov [eax+UART.mode], ecx
|
||||
|
||||
mov esi, eax
|
||||
mov bx, [divisor+ebx*2]
|
||||
|
||||
mov edx, [esi+UART.base]
|
||||
push edx
|
||||
add edx, LCR_REG
|
||||
in al, dx
|
||||
or al, 0x80
|
||||
out dx, al
|
||||
|
||||
pop edx
|
||||
mov al, bl
|
||||
out dx, al
|
||||
|
||||
inc dx
|
||||
mov al, bh
|
||||
out dx, al
|
||||
|
||||
add edx, LCR_REG-1
|
||||
mov eax, ecx
|
||||
out dx, al
|
||||
xor eax, eax
|
||||
ret
|
||||
.fail:
|
||||
or eax, -1
|
||||
ret
|
||||
|
||||
; param
|
||||
; esi= input buffer
|
||||
; +0 connection
|
||||
; +4 modem control reg valie
|
||||
;
|
||||
; retval
|
||||
; eax= error code
|
||||
|
||||
align 4
|
||||
uart_set_mcr:
|
||||
|
||||
mov eax, [esi]
|
||||
cmp [eax+APPOBJ.magic], 'CNCT'
|
||||
jne .fail
|
||||
|
||||
cmp [eax+APPOBJ.destroy], uart_close.destroy
|
||||
jne .fail
|
||||
|
||||
mov eax, [eax+CONNECTION.uart]
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
mov ebx, [esi+4]
|
||||
|
||||
mov [eax+UART.mcr_reg], ebx
|
||||
mov edx, [eax+UART.base]
|
||||
add edx, MCR_REG
|
||||
mov al, bl
|
||||
out dx, al
|
||||
xor eax, eax
|
||||
ret
|
||||
.fail:
|
||||
or eax, -1
|
||||
ret
|
||||
|
||||
; param
|
||||
; eax= port
|
||||
;
|
||||
; retval
|
||||
; ecx= connection
|
||||
; eax= error code
|
||||
|
||||
align 4
|
||||
uart_open:
|
||||
dec eax
|
||||
cmp eax, COM_MAX
|
||||
jae .fail
|
||||
|
||||
mov esi, [com1+eax*4] ;uart
|
||||
push esi
|
||||
.do_wait:
|
||||
cmp dword [esi+UART.lock], 0
|
||||
je .get_lock
|
||||
; call change_task
|
||||
jmp .do_wait
|
||||
.get_lock:
|
||||
mov eax, 1
|
||||
xchg eax, [esi+UART.lock]
|
||||
test eax, eax
|
||||
jnz .do_wait
|
||||
|
||||
mov eax, esi ;uart
|
||||
call uart_reset.internal
|
||||
|
||||
mov ebx, [CURRENT_TASK]
|
||||
shl ebx, 5
|
||||
mov ebx, [CURRENT_TASK+ebx+4]
|
||||
mov eax, CONNECTION_SIZE
|
||||
call CreateObject
|
||||
pop esi ;uart
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
mov [eax+APPOBJ.magic], 'CNCT'
|
||||
mov [eax+APPOBJ.destroy], uart_close.destroy
|
||||
mov [eax+CONNECTION.uart], esi
|
||||
mov ecx, eax
|
||||
xor eax, eax
|
||||
ret
|
||||
.fail:
|
||||
or eax, -1
|
||||
ret
|
||||
restore .uart
|
||||
|
||||
; param
|
||||
; esi= input buffer
|
||||
|
||||
align 4
|
||||
uart_close:
|
||||
mov eax, [esi]
|
||||
cmp [eax+APPOBJ.magic], 'CNCT'
|
||||
jne .fail
|
||||
|
||||
cmp [eax+APPOBJ.destroy], uart_close.destroy
|
||||
jne .fail
|
||||
.destroy:
|
||||
push [eax+CONNECTION.uart]
|
||||
call DestroyObject ;eax= object
|
||||
pop eax ;eax= uart
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
mov [eax+UART.state], UART_CLOSED
|
||||
mov [eax+UART.lock], 0;release port
|
||||
xor eax, eax
|
||||
ret
|
||||
.fail:
|
||||
or eax, -1
|
||||
ret
|
||||
|
||||
|
||||
; param
|
||||
; eax= uart
|
||||
; ebx= baud rate
|
||||
|
||||
align 4
|
||||
set_rate:
|
||||
cmp ebx, RATE_115200
|
||||
ja .fail
|
||||
|
||||
mov [eax+UART.rate], ebx
|
||||
mov bx, [divisor+ebx*2]
|
||||
|
||||
mov edx, [eax+UART.base]
|
||||
add edx, LCR_REG
|
||||
in al, dx
|
||||
push eax
|
||||
or al, 0x80
|
||||
out dx, al
|
||||
|
||||
sub edx, LCR_REG
|
||||
mov al, bl
|
||||
out dx, al
|
||||
|
||||
inc edx
|
||||
mov al, bh
|
||||
out dx, al
|
||||
|
||||
pop eax
|
||||
add edx, LCR_REG-1
|
||||
out dx, al
|
||||
.fail:
|
||||
ret
|
||||
|
||||
|
||||
; param
|
||||
; ebx= uart
|
||||
|
||||
align 4
|
||||
transmit:
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov edx, [ebx+UART.base]
|
||||
|
||||
pushfd
|
||||
cli
|
||||
|
||||
mov esi, [ebx+UART.xmit_rp]
|
||||
mov ecx, [ebx+UART.xmit_count]
|
||||
test ecx, ecx
|
||||
je .stop
|
||||
|
||||
cmp ecx, 16
|
||||
jbe @F
|
||||
mov ecx, 16
|
||||
@@:
|
||||
sub [ebx+UART.xmit_count], ecx
|
||||
add [ebx+UART.xmit_free], ecx
|
||||
cld
|
||||
@@:
|
||||
lodsb
|
||||
out dx, al
|
||||
dec ecx
|
||||
jnz @B
|
||||
|
||||
cmp esi, [ebx+UART.xmit_top]
|
||||
jb @F
|
||||
sub esi, 8192
|
||||
@@:
|
||||
mov [ebx+UART.xmit_rp], esi
|
||||
|
||||
cmp [ebx+UART.xmit_count], 0
|
||||
je .stop
|
||||
|
||||
mov [ebx+UART.state], UART_TRANSMIT
|
||||
jmp @F
|
||||
.stop:
|
||||
mov [ebx+UART.state], UART_STOP
|
||||
@@:
|
||||
popfd
|
||||
pop edi
|
||||
pop esi
|
||||
ret
|
||||
|
||||
|
||||
; param
|
||||
; esi= input buffer
|
||||
; +0 connection
|
||||
; +4 dst buffer
|
||||
; +8 dst size
|
||||
; edi= output buffer
|
||||
; +0 bytes read
|
||||
|
||||
; retval
|
||||
; eax= error code
|
||||
|
||||
align 4
|
||||
uart_read:
|
||||
mov eax, [esi]
|
||||
cmp [eax+APPOBJ.magic], 'CNCT'
|
||||
jne .fail
|
||||
|
||||
cmp [eax+APPOBJ.destroy], uart_close.destroy
|
||||
jne .fail
|
||||
|
||||
mov eax, [eax+CONNECTION.uart]
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
mov ebx, [esi+8] ;dst size
|
||||
mov ecx, [eax+UART.rcvr_count]
|
||||
cmp ecx, ebx
|
||||
jbe @F
|
||||
mov ecx, ebx
|
||||
@@:
|
||||
mov [edi], ecx ;bytes read
|
||||
test ecx, ecx
|
||||
jz .done
|
||||
|
||||
push ecx
|
||||
|
||||
mov edi, [esi+4] ;dst
|
||||
mov esi, [eax+UART.rcvr_rp]
|
||||
cld
|
||||
rep movsb
|
||||
pop ecx
|
||||
|
||||
cmp esi, [eax+UART.rcvr_top]
|
||||
jb @F
|
||||
sub esi, 8192
|
||||
@@:
|
||||
mov [eax+UART.rcvr_rp], esi
|
||||
sub [eax+UART.rcvr_count], ecx
|
||||
.done:
|
||||
xor eax, eax
|
||||
ret
|
||||
.fail:
|
||||
or eax, -1
|
||||
ret
|
||||
|
||||
; param
|
||||
; esi= input buffer
|
||||
; +0 connection
|
||||
; +4 src buffer
|
||||
; +8 src size
|
||||
;
|
||||
; retval
|
||||
; eax= error code
|
||||
|
||||
align 4
|
||||
uart_write:
|
||||
mov eax, [esi]
|
||||
cmp [eax+APPOBJ.magic], 'CNCT'
|
||||
jne .fail
|
||||
|
||||
cmp [eax+APPOBJ.destroy], uart_close.destroy
|
||||
jne .fail
|
||||
|
||||
mov eax, [eax+CONNECTION.uart]
|
||||
test eax, eax
|
||||
jz .fail
|
||||
|
||||
mov ebx, [esi+4]
|
||||
mov edx, [esi+8]
|
||||
|
||||
; param
|
||||
; eax= uart
|
||||
; ebx= src
|
||||
; edx= count
|
||||
|
||||
align 4
|
||||
.internal:
|
||||
mov esi, ebx
|
||||
mov edi, [eax+UART.xmit_wp]
|
||||
.write:
|
||||
test edx, edx
|
||||
jz .fail
|
||||
.wait:
|
||||
cmp [eax+UART.xmit_free], 0
|
||||
jne .fill
|
||||
|
||||
cmp [eax+UART.state], UART_TRANSMIT
|
||||
je .wait
|
||||
|
||||
mov ebx, eax
|
||||
push edx
|
||||
call transmit
|
||||
pop edx
|
||||
mov eax, ebx
|
||||
jmp .write
|
||||
.fill:
|
||||
mov ecx, [eax+UART.xmit_free]
|
||||
cmp ecx, edx
|
||||
jbe @F
|
||||
mov ecx, edx
|
||||
@@:
|
||||
push ecx
|
||||
cld
|
||||
rep movsb
|
||||
pop ecx
|
||||
sub [eax+UART.xmit_free], ecx
|
||||
add [eax+UART.xmit_count], ecx
|
||||
sub edx, ecx
|
||||
jnz .wait
|
||||
.done:
|
||||
cmp edi, [eax+UART.xmit_top]
|
||||
jb @F
|
||||
sub edi, 8192
|
||||
@@:
|
||||
mov [eax+UART.xmit_wp], edi
|
||||
cmp [eax+UART.state], UART_TRANSMIT
|
||||
je @F
|
||||
mov ebx, eax
|
||||
call transmit
|
||||
@@:
|
||||
xor eax, eax
|
||||
ret
|
||||
.fail:
|
||||
or eax, -1
|
||||
ret
|
||||
|
||||
|
||||
align 4
|
||||
com_2_isr:
|
||||
mov ebx, [com2]
|
||||
jmp com_1_isr.get_info
|
||||
align 4
|
||||
com_1_isr:
|
||||
mov ebx, [com1]
|
||||
.get_info:
|
||||
mov edx, [ebx+UART.base]
|
||||
add edx, IIR_REG
|
||||
in al, dx
|
||||
|
||||
test al, IIR_INTR
|
||||
jnz .done
|
||||
|
||||
shr eax, 1
|
||||
and eax, 3
|
||||
|
||||
call [isr_action+eax*4]
|
||||
jmp .get_info
|
||||
.done:
|
||||
ret
|
||||
|
||||
align 4
|
||||
isr_line:
|
||||
mov edx, [ebx+UART.base]
|
||||
add edx, LSR_REG
|
||||
in al, dx
|
||||
ret
|
||||
|
||||
align 4
|
||||
isr_recieve:
|
||||
mov esi, [ebx+UART.base]
|
||||
add esi, LSR_REG
|
||||
mov edi, [ebx+UART.rcvr_wp]
|
||||
xor ecx, ecx
|
||||
cld
|
||||
.read:
|
||||
mov edx, esi
|
||||
in al, dx
|
||||
test eax, LSR_DR
|
||||
jz .done
|
||||
|
||||
mov edx, [ebx+UART.base]
|
||||
in al, dx
|
||||
stosb
|
||||
inc ecx
|
||||
jmp .read
|
||||
.done:
|
||||
cmp edi, [ebx+UART.rcvr_top]
|
||||
jb @F
|
||||
sub edi, 8192
|
||||
@@:
|
||||
mov [ebx+UART.rcvr_wp], edi
|
||||
add [ebx+UART.rcvr_count], ecx
|
||||
ret
|
||||
|
||||
align 4
|
||||
isr_modem:
|
||||
mov edx, [ebx+UART.base]
|
||||
add edx, MSR_REG
|
||||
in al, dx
|
||||
ret
|
||||
|
||||
|
||||
align 4
|
||||
divisor dw 2304, 1536, 1047, 857, 768, 384
|
||||
dw 192, 96, 64, 58, 48, 32
|
||||
dw 24, 16, 12, 6, 3, 2, 1
|
||||
|
||||
align 4
|
||||
uart_func dd 0 ;SRV_GETVERSION
|
||||
dd 0 ;PORT_OPEN
|
||||
dd uart_close ;PORT_CLOSE
|
||||
dd uart_reset ;PORT_RESET
|
||||
dd uart_set_mode ;PORT_SETMODE
|
||||
dd 0 ;PORT_GETMODE
|
||||
dd uart_set_mcr ;PORT_SETMODEM
|
||||
dd 0 ;PORT_GETMODEM
|
||||
dd uart_read ;PORT_READ
|
||||
dd uart_write ;PORT_WRITE
|
||||
|
||||
isr_action dd isr_modem
|
||||
dd transmit
|
||||
dd isr_recieve
|
||||
dd isr_line
|
||||
|
||||
version dd (5 shl 16) or (UART_VERSION and 0xFFFF)
|
||||
|
||||
sz_uart_srv db 'UART',0
|
||||
|
||||
align 4
|
||||
|
||||
com1 rd 1
|
||||
com2 rd 1
|
||||
|
Reference in New Issue
Block a user