📄 slip.inc
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; SLIP.INC ;;
;; ;;
;; Serial Line IP network layer for Menuet OS ;;
;; ;;
;; Version 0.1 9th June 2002 ;;
;; ;;
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SLIP constants
SLIP_END equ 192
SLIP_ESC equ 219
SLIP_ESC_END equ 220
SLIP_ESC_ESC equ 221
; Transmit state machine
TX_IDLE equ 0
TX_SENDING equ 1
TX_COMPLETE equ 2
TX_SEND_ESC_ESC equ 3
TX_SEND_ESC_END equ 4
;***************************************************************************
; Interface
;
; slip_driver
; enable_slip
; disable_slip
;
;***************************************************************************
;***************************************************************************
; Function
; slip_driver
;
; Description
; The SLIP RX and TX handler
; This is a kernel function, called by stack_handler
;
;***************************************************************************
slip_driver:
; Do nothing if the driver is inactive
cmp [slip_active], byte 0
jz sd_exit
call slip_rx
call slip_tx
sd_exit:
ret
;***************************************************************************
; Function
; slip_rx
;
; Description
;
;***************************************************************************
slip_rx:
; Test recieve buffer
mov ebx, [stack_config]
and ebx, 0x0000FF00
mov cl, 12 - 8 ; the irq is already shifted 8 bits up
shl ebx, cl ; from it's position in stack_config
add ebx, 0x2E0000
mov ecx, [ebx]
cmp ecx, 0
jz sr_buff_empty ; Quit if nothing in the receive buffer
; Now check the IPbuffer recieve pointer. If none, get one
; TDB Need to handle 'no free buffers' case
cmp [rx_buff_ptr], dword 0xFFFFFFFF
jnz rx_buff_ok
; We dont have one. Therefore, find one,
; and initialise the state variables
; For now, assume that we get one.
; I'm not sure how we handle failure to get one.
mov eax, EMPTY_QUEUE
call dequeue
mov [rx_buff_ptr], eax
mov [slip_rx_state], byte 0
mov [rx_data_ptr], dword 0
rx_buff_ok:
; remove the byte from the receive queue, place in ebx
cli ; Disable interrupts. I dont want rs232
; ints coming in here
mov ecx, [ebx] ; Fetch the count again, in case the
; buffer has been updated by int
sub ecx, 1
mov esi, ebx
mov [ebx], ecx
movzx ebx, byte [ebx+0x10]
; Now tidy up the interrupt buffer
add esi, 0x10
mov edi, esi
add esi, 1
mov ecx, 4000 / 4
cld
rep movsd
sti ; re enable interrupts
; ebx = data. Process it, store the result ( possibly ).
cmp [slip_rx_state], byte 0
jnz rx_ESC_state
cmp bl, SLIP_END
jnz tryESC
cmp [rx_data_ptr], dword 0 ; If we haven't received any data
; yet, ignore END character
jz sr_exit
close_buffer:
mov ebx, [rx_buff_ptr]
mov [rx_buff_ptr], dword 0xFFFFFFFF
mov eax, IPIN_QUEUE
call queue
jmp sr_exit
tryESC:
cmp bl, SLIP_ESC
jnz storeRXByte
mov [slip_rx_state], byte 1
jmp sr_exit
storeRXByte:
mov eax, [rx_buff_ptr]
mov ecx, IPBUFFSIZE
mul ecx
add eax, IPbuffs
add eax, [rx_data_ptr]
mov [eax], bl
mov eax, [rx_data_ptr]
inc eax
mov [rx_data_ptr], eax
; Terminate the buffer if it is full (trap error case)
cmp eax, IPBUFFSIZE
jz close_buffer
jmp sr_exit
rx_ESC_state:
mov [slip_rx_state], byte 0
cmp bl, SLIP_ESC_END
jnz tryESCESC
mov bl, SLIP_END
jmp storeRXByte
tryESCESC:
cmp bl, SLIP_ESC_ESC
jnz storeRXByte
mov bl, SLIP_ESC
jmp storeRXByte
sr_exit:
; This is a bit of test code.
; Stay in here until all bytes in the rx buffer processed
; Actually made things a lot better
jmp slip_rx
sr_buff_empty:
ret
;***************************************************************************
; Function
; slip_tx
;
; Description
;
;***************************************************************************
slip_tx:
cmp [tx_buff_ptr], dword 0xFFFFFFFF; Do we have a buffer being sent?
jnz send_data ; Yes - contiue to send data
; dequeue
mov eax, NET1OUT_QUEUE
call dequeue
cmp ax, NO_BUFFER
jz st_buffer_empty
mov [tx_buff_ptr], eax
send_data:
mov al, [slip_tx_state]
cmp al, TX_IDLE
jnz tryTX_SENDING
mov [tx_data_ptr], dword 0
mov [slip_tx_state], byte TX_SENDING
mov eax, [tx_buff_ptr]
mov ecx, IPBUFFSIZE
mul ecx
add eax, IPbuffs
mov bh, [eax+2]
mov bl, [eax+3]
mov [tx_msg_len], bx ; Save the length of the packet
mov bl, SLIP_END ; Always send an END first
call tx_byte
jmp st_exit
tryTX_SENDING:
cmp al, TX_SENDING
jnz tryTX_SEND_ESC_END
mov eax, [tx_data_ptr]
cmp ax, [tx_msg_len] ; looks odd, but is ok
jnz sendDataByte
; place the buffer into the free queue
mov eax, [tx_buff_ptr]
call freeBuff
mov [tx_buff_ptr], dword 0xFFFFFFFF
mov [slip_tx_state], byte TX_IDLE
mov bl, SLIP_END ; Always send and END first
call tx_byte
jmp st_exit
sendDataByte:
mov eax, [tx_buff_ptr]
mov ecx, IPBUFFSIZE
mul ecx
add eax, IPbuffs
add eax, [tx_data_ptr]
mov bl, [eax]
cmp bl, SLIP_END
jnz trytxESC
mov [slip_tx_state], byte TX_SEND_ESC_END
mov bl, SLIP_ESC
call tx_byte
jmp st_inc
trytxESC:
cmp bl, SLIP_ESC
jnz justSend
mov [slip_tx_state], byte TX_SEND_ESC_ESC
mov bl, SLIP_ESC
call tx_byte
jmp st_inc
justSend:
call tx_byte
st_inc:
inc dword [tx_data_ptr]
jmp st_exit
tryTX_SEND_ESC_END:
cmp al, TX_SEND_ESC_END
jnz tryTX_SEND_ESC_ESC
mov [slip_tx_state], byte TX_SENDING
mov bl, SLIP_ESC_END
call tx_byte
jmp st_exit
tryTX_SEND_ESC_ESC:
cmp al, TX_SEND_ESC_ESC
jnz st_exit
mov [slip_tx_state], byte TX_SENDING
mov bl, SLIP_ESC_ESC
call tx_byte
st_exit:
; experimental repeat until tx buffer empty
jmp slip_tx
st_buffer_empty:
ret
;***************************************************************************
; Function
; tx_byte
;
; Description
; Send a byte in bl out of the com port
; destroys eax, edx
;
;***************************************************************************
tx_byte:
push ebx ; Save the byte
mov ebx, [stack_config] ;
shr ebx, 16 ; get the com port address
; Wait for transmit buffer to empty. This could take 1ms @ 9600baud
mov edx, ebx
add edx, 5
wait_tx:
in al, dx ; read uart serialisation status
and al, 0x40
cmp al, 0
jz wait_tx ; loop until free
mov edx, ebx
pop eax ; restore the byte to send
out dx, al
ret
;***************************************************************************
; Function
; enables_slip
;
; Description
; Reads the stack configuration settings, and if SLIP is
; the chosen protocol,
; takes control of the requested comm port.
; Marks slip as active
;
;***************************************************************************
enable_slip:
; Set the port to the desired speed
mov ebx, [stack_config] ; combase
shr ebx, 16
mov edx, ebx
add edx, 3 ; data format register
mov al, 0x80 ; enable access to divisor latch
out dx, al
mov edx, ebx
add edx, 1 ; interrupt enable register
mov al, 0x00 ; No interruts enabled
out dx, al
mov edx, ebx
mov al, 0xC0 / 16 ; set baud rate to 9600
out dx, al
mov edx, ebx
add edx, 3 ; data format register
mov al, 0x03 ; 8 data bits
out dx, al
mov edx, ebx
add edx, 4 ; Modem control register
; the following line was changed to +3 - in the hope that
; the Pocket PC will remain connected
; It did.
mov al, 0x08 + 3 ; out2 enabled. No handshaking.
; was 0xb, out2 enabled, RTS/DTR enabled
out dx, al
mov edx, ebx
add edx, 1 ; interrupt enable register
mov al, 0x01 ; Receive data interrupt enabled,
; others disabled
out dx, al
; clear the IRQ data buffer
mov ebx, [stack_config]
and ebx, 0x0000FF00
mov cl, 12 - 8 ; the irq is already shifted 8 bits up
; from it's position in stack_config
shl ebx, cl
add ebx, 0x2E0000
mov [ebx], dword 0
; Fly :o)
mov al, 1
mov [slip_active], al
ret
;***************************************************************************
; Function
; disable_slip
;
; Description
; Releases the resources used by the slip driver, and
; marks slip as inactive
;
;***************************************************************************
disable_slip:
; It will be a good idea to clear the IPBuffers, so that when re-enabled,
; SLIP doesn't attempt to send 'old' packets
; TBD
xor al, al
mov [slip_active], al
; Experimental.
; Turn off the modem lines. This makes SLIP work with a HP IPAQ
; Set the port to the desired speed
mov ebx, [stack_config] ; combase
shr ebx, 16
mov edx, ebx
add edx, 4 ; Modem control register
mov al, 0x08 ; out2 enabled, but RTS/DTR high
; ( inactive)
out dx, al
ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -