$mod51 $nosymbols $nolist $include(i51ctrl.inc) $include(c:\cet\inc\mymon.inc) $list $include(i51init.inc) flags data 21h ctrl bit 21h.0 parity bit 21h.1 Mrk data 24h Len data 25h Seq data 26h Typ data 27h Chk data 28h fph data 2eh fpl data 2fh cksum data 10h EOL data 11h CTL DATA 12H T data 13h N data 14h try data 15h I data 16h T7 data 17h Ptr data 18h org codeaddr start: jmp main main: mov N,#0 ; initialize sequence number clr parity ; no parity bit setb runlite ;========================================= L2000: call L5000 mov a,TYP cjne a,#'S',L2035 sjmp L2040 L2035: mov flags,#0ffh mov dptr,#D mov a,TYP movx @dptr,a inc dptr clr a movx @dptr,a call strcat db ' Packet in S State',0 jmp L9500 ; ; here on correct packet type L2040: mov dptr,#pktdat call strlen push acc ; save packet length ; ; if pktlen > 4 then EOL=asc(mid$(pktdat,5,1) else EOL=13 cjne a,#4,L2042 L2042: jc L2044 ; > 4 mov dpl,#4 movx a,@dptr call unchar mov EOL,a sjmp L2050 L2044: mov EOL,#13 ; <= 4 L2050: pop acc ; get packet length ; if pktlen > 5 then CTL=asc(mid$(pktdat,5,1) else CTL="#" cjne a,#5,L2052 L2052: jc L2054 mov dpl,#5 movx a,@dptr mov CTL,a sjmp L2070 L2054: mov CTL,#'#' L2070: mov dptr,#D clr a movx @dptr,a ; D = "" call strcat ; ; MAXL = 80 bytes ; TIME = 10 seconds ; NPAD = none ; PADC = NUL ; EOL = 13 ; QCTL = # ; QBIN = No 8th bit prefix ; CHKT = normal 6 bit checksum db 'p* @-#N1',0 ; parameter string call L8020 ; send local parameters ;========================================= ; get a File Header packet. If a B packet comes, we're all done L3000: call L5000 mov a,TYP cjne a,#'B',L3030 call L8000 jmp L9900 L3030: cjne a,#'F',L3035 sjmp L3040 L3035: mov dptr,#D mov a,TYP movx @dptr,a inc dptr clr a movx @dptr,a call strcat db ' Packet in F State',0 jmp L9500 L3040: call fopen ; open the file L3060: call L8000 ;========================================= ; get data packets. If a Z packet comes, the file is complete. L4000: call L5000 L4020: mov a,TYP cjne a,#'Z',L4030 call fclose ; close the file call L8000 jmp L3000 L4030: cjne a,#'D',L4035 sjmp L4040 ; we have data ! L4035: mov dptr,#D mov a,TYP movx @dptr,a inc dptr clr a movx @dptr,a call strcat db ' Packet in D State',0 jmp L9500 L4040: call fwrite ; write to file L4060: call L8000 ; acknowledge L4070: jmp L4000 ;========================================= ; try to get a valid packet with the desired sequence number L5000: call L7000 mov try,#1 nxttry: mov a,Seq cjne a,N,L5040 mov a,Typ cjne a,#'Q',L5090 L5040: mov dptr,#sndbuf call print call L7000 inc try mov a,try cjne a,#5,nxttry mov TYP,#'T' L5090: ret ; ;========================================= ; Send a packet with data D$ of length L, type TYP, sequence #N. L6000: mov dptr,#D push dpl push dph mov a,TYP push acc mov a,N push acc mov a,Len push acc call spack ret ; ;========================================= ; routine to read and decode a packet L7000: call rpack ret ; ;========================================= ; routine to send an ACK and increment the packet number L8000: mov dptr,#D clr a movx @dptr,a ; d$ = "" L8020: mov TYP,#'Y' mov dptr,#D call strlen mov Len,a ; L = len(D$) call L6000 ; send packet mov a,N inc a anl a,#3fh ; 63 mov N,a ; n = (n + 1) and 63 anl a,#3 jnz L8050 cpl runlite L8050: ret ; ;========================================= ; Error handler L9000: ;========================================= ; Error packet sender L9500: mov dptr,#D call strlen mov TYP,#'E' call L6000 ; send packet ; Normal exit point L9900: call fclose jmp WARM ; ;========================================= blkchk: mov b,a ; save check anl a,#192 swap a rr a rr a anl a,#3 ; a = a / 64 add a,b ; add check anl a,#63 ret ; ;========================================= linput: mov dptr,#rcvbuf linp1: push dpl push dph call getchr pop dph pop dpl movx @dptr,a inc dptr cjne a,#cr,linp1 clr a movx @dptr,a ; string terminator ret ; ;========================================= ; find char B in string DPTR return index A instr: mov r2,#0 instr1: movx a,@dptr jz instr3 inc r2 cjne a,b,instr2 sjmp instr4 instr2: inc dptr sjmp instr1 instr3: mov r2,a instr4: mov a,r2 ret ; tochar: add a,#32 ret ; unchar: clr c subb a,#32 ret ; fopen: mov dptr,#fileaddr mov fpl,dpl mov fph,dph ret ; ; write Len bytes from PKTDAT to FPTR fwrite: mov p2,#high pktdat mov r0,#low pktdat mov dpl,fpl mov dph,fph mov r2,Ptr ; pktdat length fw1: movx a,@r0 ; get byte from pktdat movx @dptr,a ; put byte to fptr inc r0 inc dptr djnz r2,fw1 mov fpl,dpl mov fph,dph ret fclose: ret ; $include(i51scat.asm) $include(i51slen.asm) $include(i51spck.asm) $include(i51rpck.asm) $include(i51chkl.asm) ; dseg at dataaddr rcvbuf: ds 128 sndbuf: ds 1,'# N3',13,0 ds 128 - ($-sndbuf) pktdat: ds 128 D: ds 128 end