title krecv/mac reception unit cseg ; ; extrn recptr,recbuf,rplus,mjump,rfjump,rdjump extrn spaket,rpaket,screen extrn rplus,sinit,state,byte,n,r extrn rpack,spack,abort,acsum,flush extrn fcb,writnx,open,rinit,close extrn lrecl public r_init,r_file,rf_b,rf_x,rf_f public r_data,rd_z,rd_d ; len equ 0 seq equ 1 type equ 2 data equ 3 quote equ '#' _a equ 1 _c equ 2 _r equ 3 _rf equ 4 _rd equ 5 ; ; subttl macros used in this module ; ;prmes to display messages ; prmes macro lab .xlist extrn m_&lab,l_&lab push hl push bc ld hl,m_&lab ld bc,(l_&lab) ld c,13 ld a,9 rst 8 pop bc pop hl .list endm ;movb ; movb macro value,loc .xlist push af ld a,value ld (loc),a pop af .list endm ; ;blmov ; blmov macro source,dest,len .xlist local $1,$2 push hl push bc push de ld hl,source ld de,dest ld a,(len) cp 0 jr nz,$1 ld b,1 ld c,0 jp $2 $1: ld b,0 ld c,a $2: ldir pop de pop bc pop hl .list endm ; ;fack to format an ack paket ; f_ack macro .xlist ld (iy+len),3 ld a,(n) add a,' ' ld (iy+seq),a ld (iy+type),'Y' ld hl,spaket call acsum .list endm ; ;nplus ; nplus macro .xlist ld hl,n inc (hl) res 6,(hl) ;not over 63 .list endm ; subttl receive initialize ; ; receive init ; r_init: movb 0,n ;set packet count to 0 movb 0,r ;and retry count to 0 ld ix,rpaket ;ix will always point there call flush ;flush comm port call rpack ;and get a packet jp c,rplus ;no good, nack, r+ ld a,(ix+type) ;get packet type cp 'S' ;is it a send ? jp nz,abort ;nope, no good movb 10,byte ;will move 10 bytes blmov rpaket+data,sinit,byte ;to send init buffer ld hl,sinit+4 ;address of eol res 5,(hl) ;sub 32 to get real eol ;and prepare to ack ;with our parameters ld iy,spaket ;iy will always point there ld (iy+len),12 ;length ld (iy+type),'Y' ;ack ld a,(n) ;current packet number add a,32 ;make printable ld (iy+seq),a ;save in ack packet blmov rinit,spaket+data,byte ;all the info ld hl,spaket ;hl points to send packet call acsum ;add checksum call spack ;and pray it gets there nplus ;increment n movb 0,r ;set retry count to 0 movb _rf,state ;to receive file jp mjump ;back subttl receive file page ; ; receive file ; r_file: call rpack ;get a packet jp c,rplus ;no good ld a,(n) ;packet number expected add a,' ' ;make printable cp (ix+seq) ;equal to received packet jp z,rfgood ;yes call spack ;re-ack, it was lost jp rplus ;increment r, nak rfgood: jp rfjump ;jump according to table rf_b: ;case(break) f_ack ;format ack call spack ;and send it nplus movb _c,state ;set state to complete jp mjump ;and back rf_x: ;case(type on screen) movb 1,screen ;set flag on movb _rd,state ;set state to receive data f_ack ;format ack call spack ;and send it nplus ;increment packet count jp mjump ;and back rf_f: ;case(file header) ld a,(ix+len) ;get lenght sub ' '+3 ;minus seq,type, chksum ld (ix+len),a ;store back blmov rpaket+data,fcb,rpaket ;move filename to fcb ld hl,fcb ;start of filename ld c,a ;length ld b,0 ;bc = length ld a,'.' ;to scan for dot cpir ;found dot dec hl ;adjust pointer ld (hl),'/' ;replace by '/' ld a,0 ;clr a cp c ;c = 0 ? jp z,r_f0 ;yes, put in cr ld hl,fcb ;first byte of filename ld a,(rpaket) ;length of filename add a,l ;add low byte to length ld l,a ;store back low byte ld a,0 ;clear a adc a,h ;add high byte to carry ld h,a ;put back in h r_f0: ld (hl),13 ;put in a carriage return call open ;and open file f_ack ;format an ack call spack ;and send it nplus ;increment packet count movb _rd,state ;set state to receive data jp mjump ;and back subttl receive data page ; ; receive data ; r_data: call rpack ;get a packet jp c,rplus ;no good ld a,(n) ;get expected packet count add a,' ' ;make printable cp (ix+seq) ;equal to received ? jp z,rdgood ;yes, all ok call spack ;re-ack, it was lost jp rplus ;update retry count rdgood: jp rdjump rd_z: ;case(end of file) call writnx ;flush buffer call close ;close file f_ack ;format an ack call spack ;and send it nplus ;increment packet count movb _rf,state ;set state to receive file jp mjump ;and back rd_d: ;case(data) ld hl,rpaket+data ;start of data ld a,(rpaket) ;total length sub ' '+3 ;convert to numeric cp 0 ;is it null ? jp z,rd_d2 ;yes, finish ld bc,(recptr) ;pointer inside recbuf ld b,0 ;turn off high byte push hl ;save temporarily ld hl,recbuf ;record address add hl,bc ;plus length ex de,hl ;pointer in de pop hl ;restore hl ;at this point : ; hl = rpaket ; de = inside recbuf ; a = length of packet rd_d1: push af ;save temporarily ld a,(hl) ;get current byte cp quote ;is it a quote ? jr nz,rd_d3 ;no, go on inc hl ;point to next byte pop af ;restore a dec a ;decrement counter push af ;and save again ld a,(hl) ;get next byte cp quote ;is it a quote ? jr z,rd_d3 ;yes, don't touch cp quote or 128 ;quote and eight bit jr z,rd_d3 ;yes don't touch either xor 64 ;uncontrollify ld (hl),a ;store back rd_d3: pop af ;restore ldi ;from rapket to recbuf dec a ;paket length minus one ld bc,(recptr) ;pointer inside recbuf inc c ;is incremented movb c,recptr ;and stored back push af ;save a ld a,(lrecl) ;get logical record length cp c ;compare to len(recbuf) jp nz,rd_d0 ;no, do not update yet call writnx ;write next record movb 0,recptr ;set pointer back to zero ld de,recbuf ;reset pointer to record buffer rd_d0: pop af ;restore a cp 0 ;is packet empty ? jp nz,rd_d1 ;no, get one more byte rd_d2: f_ack ;format an ack call spack ;and send it nplus ;update packet counter jp mjump ;and back end