⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 slip.inc

📁 Menuet 操作系统源代码。 非常难得的东西
💻 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 + -