home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
assemblr
/
library
/
sampler0
/
send.asm
< prev
next >
Wrap
Assembly Source File
|
1986-07-14
|
15KB
|
354 lines
Page 55,132
Title SEND - Send a file using XMODEM protocol
SPECIAL Equ 0 ;If true, include data size in block
If SPECIAL
BLOCK Struc
B_SOH Db 001H ;Start of header
B_BLK1 Db 000H ;Block number
B_BLK2 Db 0FFH ;(Block number)'
B_CNT Db ? ;Count of bytes used in the data area
B_DATA Db 128 Dup (?) ;The data area
B_CHKSUM Db ? ;Checksum of the data
BLOCK Ends
Else
BLOCK Struc
B_SOH Db 001H ;Start of header
B_BLK1 Db 000H ;Block number
B_BLK2 Db 0FFH ;(Block number)'
B_DATA Db 128 Dup (?) ;The data area
B_CHKSUM Db ? ;Checksum of the data
BLOCK Ends
Endif
ERROR Macro N
Mov AH,09H ;Display the error message
Lea DX,ERRMSG&N ;
Int 021H ;
Mov AX,04C10H+N ;And leave
Int 021H ;
Endm
CODE Segment Public 'CODE'
CODE Ends
DATA Segment Public 'DATA'
BAUD_TABLE Label Word
Dw 9600 ;
Dw 4800 ;
Dw 2400 ;
Dw 1200 ;
Dw 600 ;
Dw 300 ;
Dw 150 ;
Dw 110 ;
FILENAME Db 64 Dup (0) ;Name of file to send
BUFFER BLOCK <> ;The block buffer
ERRMSG0 Db '?No input file specified',13,10,'$'
ERRMSG1 Db '?Unable to open input file',13,10,'$'
ERRMSG2 Db '?Invalid baud rate specified',13,10,'$'
ERRMSG3 Db '?Receiver time-out occurred',13,10,'$'
ERRMSG4 Db '?Error while reading the input file',13,10,'$'
ERRMSG5 Db '^C',13,10,'%Transmission aborted via control-C',13,10,'$'
TXTMSG1 Db 'Waiting for receiver...',13,10,'$'
TXTMSG2 Db 'Block number '
TXTNUM2 Db '0 ',13,'$'
TXTMSG3 Db 10,'Transmission complete',13,10,'$'
TXTMSG4 Db 'No retries needed',13,10,'$'
TXTMSG5 Db 'Retry count was '
TXTNUM5 Db '0 ',13,10,'$'
MODE Db 11101011B ;9600 baud, odd parity, 1 stop bit,
;8 bit character
BLOCK_COUNT Dw 0 ;Total block count
RETRY_COUNT Dw 0 ;Retry count
DATA Ends
STACK Segment Stack 'STACK'
Dw 128 Dup (?) ;Program stack
STACK Ends
CODE Segment Public 'CODE'
Assume CS:CODE,DS:Nothing,ES:Nothing,SS:STACK
MAIN Proc Near
Sti ;Enable interrupts
Mov AX,DATA ;Set up ES
Mov ES,AX ;
Assume ES:DATA
Cld ;Make sure the direction flag is clear
Mov SI,080H ;Use SI to get the file name
Lodsb ;Get the length
Or AL,AL ;Is there anything??
Jnz MAIN01 ;Yes. Proceed
MAIN00: Mov AX,ES ;Set up DS
Mov DS,AX ;
Assume DS:DATA
ERROR 0 ;Nope. Die!
Assume DS:Nothing
MAIN01: Cbw ;Make it a word count
Mov CX,AX ;Copy to CX
MAIN05: Jcxz MAIN00 ;If nothing left, error!
Dec CX ;Decrement the character count
Lodsb ;And get the character
Cmp AL,020H ;Space or less??
Ja MAIN10 ;Nope. Start the file name
Jmp Short MAIN05 ;Try again...
MAIN10: Lea DI,FILENAME ;Point DI to the file name buffer
MAIN11: Stosb ;Store the character
Jcxz MAIN20 ;Got the file name. Open the file
Dec CX ;Decrement the character count
Lodsb ;Get the next character
Cmp AL,020H ;Is it a displayable character
Ja MAIN11 ;Yes. Put it in the file name
MAIN13: Jcxz MAIN20 ;No more characters?
Dec CX ;Decrement the count
Lodsb ;Get another character
Cmp AL,020H ;Space or less??
Ja MAIN15 ;Yes. See if it's a number
Jmp Short MAIN13 ;Keep looking
MAIN15: Xor DX,DX ;Clear DX
MAIN16: Cmp AL,'0' ;Is this a digit??
Jae MAIN18 ;Yes.
MAIN17: ERROR 2 ;Not a valid baud rate
MAIN18: Cmp AL,'9' ;Still a digit??
Ja MAIN17 ;Nope.
Sub AL,'0' ;Convert to binary
Cbw ;Convert to a word
Shl DX,1 ;Double the previous number
Mov BX,DX ;Save in BX for a bit
Shl DX,1 ;
Shl DX,1 ;
Add DX,BX ;Now DX = (Old DX)*10
Add DX,AX ;Add in the last digit
Jcxz MAIN19 ;All done.
Dec CX ;Decrement the character count
Lodsb ;And get a character
Cmp AL,020H ;Space or less?
Ja MAIN16 ;
MAIN19: Mov AX,DX ;Put the baud rate in AX
Lea DI,BAUD_TABLE ;Point to the baud rate table
Mov CX,8 ;Eight entries in the table
Repne Scasw ;Look for this baud rate
Jne MAIN17 ;No good! Die!
Mov AL,CL ;Get the index
Mov CL,5 ;And position it
Shl AL,CL ;
Or AL,00001011B ;Odd parity, 1 stop bit, 8 bit character
Mov MODE,AL ;And save it
MAIN20: Mov AX,ES ;Set up DS
Mov DS,AX ;
Assume DS:DATA
Mov AX,03D00H ;Open the file for read-only
Lea DX,FILENAME ;
Int 021H ;
Jnc MAIN25 ;Proceed!
ERROR 1 ;File not found!
MAIN25: Mov BX,AX ;Put the handle in BX
Xor AH,AH ;Initialize the RS232 channel
Mov AL,MODE ;
Xor DX,DX ;On channel zero
Int 014H ;
Mov AH,09H ;Display the "Waiting..." message
Lea DX,TXTMSG1 ;
Int 021H ;
Mov CX,64 ;This shall be our original timeout
MAIN30: Mov AH,06H ;See if a character is waiting
Mov DL,0FFH ;
Int 021H ;
Jz MAIN32 ;Nope.
Cmp AL,3 ;Is it a control-C??
Jne MAIN32 ;
Mov AH,03EH ;Close the input file
Int 021H ;
ERROR 5 ;And die
MAIN32: Mov AH,02H ;Get a character from the serial port
Xor DX,DX ;(channel 0)
Int 014H ;
Test AH,08EH ;Any error occurred??
Jnz MAIN31 ;Yes. Ignore it.
Cmp AL,015H ;Is this a NAK??
Je MAIN35 ;Yes. Start the transmission.
MAIN31: Loop MAIN30 ;Repeat until CX = 0
Mov AH,03EH ;Close the input file
Int 021H ;
ERROR 3 ;And die!
MAIN35: Mov AH,03FH ;Read the file
Mov CX,128 ;Up to 128 bytes
Lea DX,BUFFER.B_DATA ;Into our buffer
Int 021H ;
Jnc MAIN40 ;Got it; now ship it
Mov AH,03EH ;Close the input file
Int 021H ;
ERROR 4 ;And die (for some unknown reason)
MAIN40: Or AX,AX ;Did we reach the end of the file??
Jz MAIN80 ;Yes. Tell the receiver
Inc BUFFER.B_BLK1 ;Adjust the block numbers
Dec BUFFER.B_BLK2 ;
If SPECIAL
Mov BUFFER.B_CNT,AL ;Store the count of bytes used
Endif
Inc BLOCK_COUNT ;Increment the block count
Lea SI,BUFFER.B_DATA ;Compute the checksum
Xor AH,AH ;Clear AH
Xor DX,DX ;Keep the checksum in DX
Mov CX,128 ;Repeat for 128 bytes
MAIN45: Lodsb ;Get a byte
Add DX,AX ;Add it to DX
Loop MAIN45 ;And repeat
Mov AX,DX ;Put the sum in AX
Mov DL,255 ;Now divide by 255
Div DL ;
Mov BUFFER.B_CHKSUM,AH ;Store the remainder as the checksum
Lea DI,TXTNUM2 ;Fill in the block number
Mov AX,BLOCK_COUNT ;
Call FILL_NUM ;
Mov AH,09H ;Display the block number
Lea DX,TXTMSG2 ;
Int 021H ;
;
; Send the block we have
;
MAIN50: Lea SI,BUFFER ;Point to the block
Mov CX,(Size BLOCK) ;Get the size of the block
MAIN51: Lodsb ;Get the byte to send
Mov AH,01H ;Send the byte
Xor DX,DX ;On channel zero
Int 014H ;
Loop MAIN51 ;
Call GET_RESPONSE ;Get the response
Cmp AL,015H ;Negative acknowledgement??
Je MAIN50 ;Yes. Try again
Jmp MAIN35 ;Go get the next piece (of ass?)
;
; End of file...
;
MAIN80: Mov AH,09H ;Display the EOT message
Lea DX,TXTMSG3 ;
Int 021H ;
MAIN82: Mov AX,0104H ;Send the EOT
Xor DX,DX ;
Int 014H ;
Call GET_RESPONSE ;Get the response
Cmp AL,015H ;Negatory??
Je MAIN82 ;Yes. Try again!
MAIN90: Mov AH,03EH ;Close the input file
Int 021H ;
Cmp RETRY_COUNT,0 ;Did we have to do any retries??
Jne MAIN95 ;Yes. Fill in the number and display it
Mov AH,09H ;No retries needed
Lea DX,TXTMSG4 ;
Int 021H ;
Jmp Short MAIN99 ;Leave
MAIN95: Lea DI,TXTNUM5 ;Point to the buffer
Mov AX,RETRY_COUNT ;Get the count
Call FILL_NUM ;
Mov AH,09H ;And display the message
Lea DX,TXTMSG5 ;
Int 021H ;
MAIN99: Mov AX,04C00H ;And leave
Int 021H ;
MAIN Endp
;
; Get a positive or negative response from the receiver.
;
GET_RESPONSE Proc Near
Mov AH,06H ;See if a character is waiting
Mov DL,0FFH ;
Int 021H ;
Jz GETR20 ;Nope.
Cmp AL,3 ;Is it a control-C??
Jne GETR20 ;
Mov AH,03EH ;Close the input file
Int 021H ;
ERROR 5 ;And leave
GETR20: Mov AH,02H ;Get a character from the serial port
Xor DX,DX ;(channel zero)
Int 014H ;
Test AH,08EH ;Did an error occur??
Jnz GET_RESPONSE ;Yes. Ignore the character
Cmp AL,005H ;Is this an ACK??
Je GETR30 ;Yes. Leave
Cmp AL,015H ;How 'bout a NAK??
Jne GET_RESPONSE ;Nope. Check again!
Inc RETRY_COUNT ;Bump the retry count
GETR30: Ret ;And return
GET_RESPONSE Endp
;
;
;
FILL_NUM Proc Near
Xor CX,CX ;Clear the character count
Mov SI,10 ;Use SI to divide with
FILL10: Xor DX,DX ;
Div SI ;Divide DX:AX by SI (10)
Add DL,'0' ;Convert DL to ASCII
Push DX ;Save it on the stack
Inc CX ;Increment the character count
Or AX,AX ;Any more to do??
Jnz FILL10 ;Yes. Keep going
Cld ;(just to be sure)
FILL20: Pop AX ;Get a character from the stack
Stosb ;And store it
Loop FILL20 ;Repeat CX times
Ret ;And return
FILL_NUM Endp
CODE Ends
End MAIN