147 lines
4.7 KiB
NASM
147 lines
4.7 KiB
NASM
|
; slip.asm
|
||
|
;
|
||
|
; This is an 8086+ implementation of SLIP (RFC 1055)
|
||
|
;
|
||
|
; It may be assembled using Microsoft's MASM using the command line:
|
||
|
; ml -Fl -c slip.asm
|
||
|
;
|
||
|
; or using Borland's TASM using the command line:
|
||
|
; tasm -la -m2 -jLOCALS slip.asm
|
||
|
;
|
||
|
.model small
|
||
|
.stack 100h
|
||
|
.data
|
||
|
SLIP_END equ 0C0h
|
||
|
SLIP_ESC equ 0DBh
|
||
|
SLIP_ESC_END equ 0DCh
|
||
|
SLIP_ESC_ESC equ 0DDh
|
||
|
|
||
|
; note that these are both sample macros and are very simple
|
||
|
; In both cases, DX is assumed to already be pointing to the
|
||
|
; appropriate I/O port and a character is always assumed to
|
||
|
; be ready.
|
||
|
SEND_CHAR macro char
|
||
|
IFDIFI <char>, <al>
|
||
|
mov al,char
|
||
|
ENDIF
|
||
|
out dx,al
|
||
|
endm
|
||
|
|
||
|
RECV_CHAR macro
|
||
|
in al,dx
|
||
|
endm
|
||
|
.code
|
||
|
;****************************************************************************
|
||
|
; send_packet
|
||
|
;
|
||
|
; sends the passed packet (which is in a memory buffer) to the output
|
||
|
; device by using the macro SEND_CHAR() which must be defined by the
|
||
|
; user. A sample SEND_CHAR() is defined above.
|
||
|
;
|
||
|
; Entry:
|
||
|
; DS:SI ==> raw packet to be sent
|
||
|
; CX = length of raw packet to be sent
|
||
|
; direction flag is assumed to be cleared (incrementing)
|
||
|
;
|
||
|
; Exit:
|
||
|
;
|
||
|
;
|
||
|
; Trashed:
|
||
|
; none
|
||
|
;
|
||
|
;****************************************************************************
|
||
|
send_packet proc
|
||
|
push cx
|
||
|
push si
|
||
|
SEND_CHAR SLIP_END ; send an end char to flush any garbage
|
||
|
jcxz @@bailout ; if zero length packet, bail out now
|
||
|
@@nextchar:
|
||
|
lodsb ; load next char
|
||
|
cmp al,SLIP_END ; Q: is it the special END char?
|
||
|
jne @@check_esc ; N: check for ESC
|
||
|
SEND_CHAR SLIP_ESC ; Y: send ESC + ESC_END instead
|
||
|
mov al,SLIP_ESC_END ;
|
||
|
jmp @@ordinary ;
|
||
|
|
||
|
@@check_esc:
|
||
|
cmp al,SLIP_ESC ; Q: is it the special ESC char?
|
||
|
jne @@ordinary ; N: send ordinary char
|
||
|
SEND_CHAR SLIP_ESC ; Y: send ESC + ESC_END instead
|
||
|
mov al,SLIP_ESC_ESC ;
|
||
|
; fall through to ordinary character
|
||
|
|
||
|
@@ordinary:
|
||
|
SEND_CHAR al ;
|
||
|
|
||
|
loop @@nextchar ; keep going until we've sent all chars
|
||
|
@@bailout:
|
||
|
SEND_CHAR SLIP_END ; send an end char to signal end of packet
|
||
|
pop si
|
||
|
pop cx
|
||
|
ret
|
||
|
send_packet endp
|
||
|
|
||
|
;****************************************************************************
|
||
|
; recv_packet
|
||
|
;
|
||
|
; receives a packet using the macro RECV_CHAR() which must be defined by
|
||
|
; the user and places the received packet into the memory buffer pointed
|
||
|
; to by ES:DI. The final length is returned in BX.
|
||
|
;
|
||
|
; Note that in the case of a buffer overrun, the portion of the packet
|
||
|
; that fit into the buffer is returned and BX and CX are equal. There
|
||
|
; is no way to tell the difference between a packet that just exactly
|
||
|
; fit and one which was truncated due to buffer overrun, so it is
|
||
|
; important to assure that the buffer is big enough to ALWAYS contain
|
||
|
; at least one spare byte.
|
||
|
;
|
||
|
; A sample RECV_CHAR() is defined above.
|
||
|
;
|
||
|
; Entry:
|
||
|
; ES:DI ==> packet buffer
|
||
|
; CX = length of buffer
|
||
|
; direction flag is assumed to be cleared (incrementing)
|
||
|
;
|
||
|
; Exit:
|
||
|
; BX = length of packet received
|
||
|
;
|
||
|
; Trashed:
|
||
|
; none
|
||
|
;
|
||
|
;****************************************************************************
|
||
|
recv_packet proc
|
||
|
push cx
|
||
|
push di
|
||
|
xor bx,bx ; zero received byte count
|
||
|
jcxz @@bailout ; if zero length packet, bail out now
|
||
|
@@nextchar:
|
||
|
RECV_CHAR ; fetch a character into al
|
||
|
cmp al,SLIP_END ; Q: is it the special END char?
|
||
|
jne @@check_esc ; N: check for ESC
|
||
|
or bx,bx ; YQ: is it the beginning of packet?
|
||
|
jz @@nextchar ; Y: keep looking
|
||
|
jmp @@bailout ; N: end of packet, so return it
|
||
|
|
||
|
@@check_esc:
|
||
|
cmp al,SLIP_ESC ; Q: is it the special ESC char?
|
||
|
jne @@ordinary ; N: it's an ordinary char
|
||
|
RECV_CHAR ; Y: get another character
|
||
|
cmp al,SLIP_ESC_END ; Q: is it ESC_END?
|
||
|
jne @@check_esc_esc ; N: check for ESC_ESC
|
||
|
mov al,SLIP_END ; Y: convert to ordinary END char
|
||
|
jmp @@ordinary ;
|
||
|
@@check_esc_esc:
|
||
|
cmp al,SLIP_ESC_ESC ; Q: is it ESC_ESC?
|
||
|
mov al,SLIP_ESC ; Y: convert to ordinary ESC char
|
||
|
; protocol violation! fall through to ordinary character
|
||
|
|
||
|
@@ordinary:
|
||
|
stosb ; store character in buffer
|
||
|
inc bx ; got another char
|
||
|
loop @@nextchar ; keep going until we've sent all chars
|
||
|
@@bailout:
|
||
|
pop di
|
||
|
pop cx
|
||
|
ret
|
||
|
recv_packet endp
|
||
|
END
|