1 REM Ins{nd av: Kristoffer Eriksson <5357> 1988-04-02 03.09.59 (WRITE) ; Fil: KERMPACK.ASM ; Av: Kristoffer Eriksson, "SKE" <5357>, 1987. ; ;-Ver--/-Datum----/-Sign-/-Kommentar---------------------------------- ; 1.00 / 87-08-15 / SKE / KERMPACK ; ; Packnings- och uppackningsrutiner till Bo Kullmars Kermit-program K. ;* Packa upp buffert. ;* In: DE pekare till inparametrar enligt: UInbuff: = +0 ;W Inbuffertens adress UInbuffs: = +2 ;B Inbuffertens slutposition eller l{ngd-1 (0-255) UUtbuff: = +3 ;W Utbuffertens adress UUtbuffl: = +5 ;B Utbuffertens l{ngd i antal byte (94-255) Qctl: = +6 ;B Tecken som markerar "tecken XOR 64" Qbin: = +7 ;B Tecken som markerar "tecken OR 128" Rept: = +8 ;B Tecken som markerar "tecken1-32 stycken tecken2" ;* In- och utbuffertarnas f|rsta byte anger n{sta oanv{nda position i resp ;* buffert, r{knat med sig sj{lva som position noll. De uppdateras med ;* aktuella v{rden vid retur. ;* ;* Inbuffertens position kan bli upp till 5 h|gre {n dess slutposition, ;* vilket inneb{r att om slutpositionen {r 251 eller mer kan man f|rlora ;* positionens mest signifikanta bittar, varvid v{rdet blir 256 f|r l}gt. ;* Detta beror p} att positionen bara kontrolleras mot l{ngden en g}ng f|r ;* varje avkodat tecken, och varje tecken kan vara kodat med upp till 5 byte. ;* [ven om bufferten bara inneh}ller korrekta koder, slutar positionen 1 ;* steg f|rbi slutpositionen (det blir ju f|rsta oanv{nda position), och ;* {r l{ngden 255 blir det 0 som lagras som position. ;* ;* Rutinen avbryts n{r n{sta inposition blir st|rre {n slutpositionen ;* (Inpos > Inslut), eller det blir 93 eller f{rre tecken kvar i utbufferten ;* (Utpos >= Utl{ngd - 93). Det senare vilkoret {r f|r att garantera att ;* en Rept-sekvens f}r plats vid uppackning. Den kan bli max 94 tecken. ;* ;* Rutinen returnerar i HL aktuell inposition - inl{ngden. Observera att ;* h{r f|rlorar man inte n}gra signifikanta bittar i positionen. ;* ;* Qctl, Qbin och Rept kan vara noll f|r att markera att de inte anv{nds. ; DE = Aktuell adress i utbuff, D' = Position i utbuff, E' = L{ngd av utbuff, ; HL = Aktuell adress i inbuff, BC' = Position i inbuff, ; B = Repetitionsfaktor, C = OR-faktor. ; Inbuff-positionen ligger i ett dubbelregister eftersom den inte kontrolleras ; mot l{ngden vid varje |kning, och d{rf|r kan r}ka bli h|gre {n 255. Unpbuff: push de pop ix ld l,(ix+UUtbuff) ld h,(ix+UUtbuff+1) ld c,(hl) ld b,0 add hl,bc ex de,hl ; DE <- Aktuell adress i utbuffert. ld a,c exx ld d,a ; D' <- Position i utbuffert. ld e,(ix+UUtbuffl) ; E' <- Utbuffertens l{ngd. exx ld l,(ix+UInbuff) ld h,(ix+UInbuff+1) ld c,(hl) ; (B = 0) add hl,bc ; HL <- Aktuell adress i inbuffert. push bc exx pop bc ; BC' <- Position i inbuffert. ULoop: ld a,e sub 94 cp d ; J{mf|r (E' - 94) med D' jr c UEnd ; Avsluta om Utpos > Utl{ngd - 94. ld a,b and a jr nz UEnd ; Inpos > 255, allts} Inpos > Inslut. ld a,(ix+UInbuffs) cp c jr c UEnd ; Avsluta om Inpos > Inslut. UCont: inc bc ; \ka Inpos i BC'. exx ld a,(hl) ; L{s Inbuffert och |ka Inadress. inc hl ld bc,1 << 8 + 0 ; B <- Reptfaktor 1, C <- OR-faktor 0. and a ; Ingen id` att j{mf|ra tecknet 0 med jr z UStoreChar ; specialtecknen, f|r {r de noll ; betyder det bara att de inte anv{nds. UchkRept: cp (ix+Rept) jr nz UchkQbin ld a,(hl) ; H{mta n{sta byte = Repetitionsfaktor. inc hl sub 32 cp 94 jr c Ux1 ; A <- max(A,94). S{kerhetskontroll, ld a,94 ; borde snarare meddela fel. Ux1: ld b,a ; B <- Repetitionsfaktor. ld a,(hl) ; A <- Repeterat tecken. inc hl exx inc bc ; \ka Inpos. inc bc exx UchkQbin: cp (ix+Qbin) jr nz UchkQctl ld c,128 ; OR-faktor f|r teckenkod. ld a,(hl) ; A <- P}verkat tecken. inc hl exx inc bc ; \ka Inpos. exx UchkQctl: cp (ix+Qctl) jr nz UStoreChar ld a,(hl) ; A <- P}verkat tecken. inc hl exx inc bc ; \ka Inpos. ld l,a ; L' <- A (tempor{r lagring). and 127 jr z Ux2 cp (ix+Rept) ; S}lla bort tecken som inte p}verkas. jr z Ux3 cp (ix+Qbin) jr z Ux3 cp (ix+Qctl) jr z Ux3 Ux2: ld a,l xor 64 jr Ux4 Ux3: ld a,l Ux4: exx UStoreChar: or c ; OR-faktor UStoreLoop: ld (de),a ; Lagra tecken i Utbuffert. inc de exx inc d ; \ka Utpos. exx djnz UStoreLoop ; Repetitionsfaktor. exx jr ULoop UEnd: ld l,(ix+UUtbuff) ld h,(ix+UUtbuff+1) ld (hl),d ; (Utbuff) <- D' = Position i utbuffert. ld l,(ix+UInbuff) ld h,(ix+UInbuff+1) ld (hl),c ; (Inbuff) <- BC' = Position i inbuffert. ld l,c ld h,b ld c,(ix+UInbuffs) xor a ; Nolla carry och A. ld b,a sbc hl,bc ; Returv{rde HL <- Inposition - Inl{ngd. ret ;* Packa buffert. ;* In: DE pekare till inparametrar enligt: PUtbuff: = +0 ;W Inbuffertens adress PUtbuffl: = +2 ;B Inbuffertens l{ngd i antal byte (10-255) PInbuff: = +3 ;W Utbuffertens adress ReptPos: = +5 ;B (Intern variabel, aktuell utpos vid start av rept.) ;Qctl: = +6 ;B Tecken som markerar "tecken XOR 64" ;Qbin: = +7 ;B Tecken som markerar "tecken OR 128" ;Rept: = +8 ;B Tecken som markerar "tecken1-32 stycken tecken2" ;* In- och utbuffertarnas f|rsta byte anger n{sta oanv{nda position i resp ;* buffert, r{knat med sig sj{lva som position noll. Dessa uppdateras med ;* aktuella v{rden f|re retur. Inbuffertens andra byte anger dess l{ngd ;* (0-255) i antal byte inklusive position och l{ngd-bytes. ;* ;* Rutinen avbryts n{r det }terst}r nio eller f{rre tecken i utbufferten ;* (Utpos >= Utl{ngd - 9) eller inbuffert {r slut (Inpos >= Inl{ngd). ;* Marginalen i utbufferten {r till f|r att kodningen av n{sta tecken ;* garanterat ska f} plats. Fast den {r on|digt stor, eftersom kodningen ;* av ett tecken kan bli max 5 tecken. ;* ;* Returnerar i HL -1 om aktuell inposition {r lika med inl{ngden, annars 0. ;* ;* Qctl, Qbin och Rept kan vara noll f|r att markera att de inte anv{nds. ; DE = Aktuell adress i utbuff, D' = Position i utbuff, E' = L{ngd av utbuff, ; HL = Aktuell adress i inbuff, B' = Position i inbuff, C' = L{ngd av inbuff, ; HL' = Adress i utbuff f|r ev repetionssekvens, B = Repetitionsr{knare. Packbuff: push de pop ix ld l,(ix+PUtbuff) ld h,(ix+PUtbuff+1) ld c,(hl) ; Position. ld b,0 add hl,bc ex de,hl ; DE <- Aktuell adress i utbuffert. ld a,c exx ld d,a ; D' <- Position i utbuffert. ld e,(ix+PUtbuffl) ; E' <- Utbuffertens l{ngd. exx ld l,(ix+PInbuff) ld h,(ix+PInbuff+1) ld c,(hl) ; Position. inc hl ld b,(hl) ; L{ngd. dec hl push bc ld b,0 add hl,bc ; HL <- Aktuell adress i inbuffert. exx pop hl ld b,l ; B' <- Position i inbufferten. ld c,h ; C' <- Inbuffertens l{ngd. ; Repetitionsr{knaren B {r nu noll. PLoop: ld a,e sub 10 cp d ; J{mf|r (E' - 10) med D' jr c PEnd ; Avsluta om Utpos > Utl{ngd - 10. ld a,c cp b ; J{mf|r C' med B'. jr z PEnd jr nc PCont ; Avsluta om Inpos >= Inl{ngd. PEnd: ld l,(ix+PUtbuff) ld h,(ix+PUtbuff+1) ld (hl),d ; (Utbuff) <- D' = Position i utbuffert. ld l,(ix+PInbuff) ld h,(ix+PInbuff+1) ld (hl),b ; (Inbuff) <- B' = Position i inbuffert. inc hl ld (hl),c ; (Inbuff+1) <- C' = L{ngd. ld a,b cp c ld hl,0 ret nz dec hl ; Returv{rde HL <- Inpos = Inl{ngd. ret PCont: inc b ; \ka Inpos i B' redan nu. exx ld a,(ix+Rept) and a jr z PchkQbin ; Ingen repetitionskomprimering. ld a,(hl) ; Aktuellt tecken. dec hl cp (hl) ; J{mf|r tecknet med f|rra tecknet. inc hl jr nz PInitRept inc b ; \ka repetitionsr{knaren. ld a,b cp 5 jr c Px1 ; Hoppa om inte B > 4. push bc ld a,(ix+Rept) exx ld (hl),a ; Anv{nd den sparade utpekaren och inc hl ; {ndra i utbufferten till repetitions- pop af ; A <- B = Rept.r{kn. sekvens med add 32 ; , samt }terst{ll ld (hl),a ; utadressen och utpositionen till push hl ; slutet av denna sekvens. dec hl ld d,(ix+ReptPos) inc d inc d exx pop de inc de cp 94+32 ; J{mf|r B med 94. (A {r nu B+32) jr nz PchkQbin ld b,0 ; Avbryt repeteringsbehandling efter jr PchkQbin ; maxantalet 94 upprepningar. PLoop2: jr PLoop ; (F|r l}ngt f|r ett enda jr-hopp.) Px1: dec a ; Om f|rra v{rdet p} rept-r{knaren var jr nz PchkQbin ; noll, ska den startas om. PInitRept: ld b,1 ; Tecknet {r inte likt f|reg}ende. push de ; Starta om repetitionsr{knare och exx ; spara utadress och utposition. pop hl ld (ix+ReptPos),d exx PchkQbin: ld a,(hl) ; Aktuellt tecken. inc hl ; Inbuffertadressen|kas f|rst nu. ld c,a cp 128 jr c PchkQctl ; Behandla tecken >= 128 med Qbin ld a,(ix+Qbin) and a jr z PchkQctl ; Avst{ngt. ld (de),a ; Lagra . inc de exx inc d ; \ka Utpos. exx ld a,c and 127 ; Nu slipper vi h|ga bitten. ld c,a PchkQctl: ld a,(ix+Qctl) and a jr z PStoreChar ; Ingen hantering av ctrl-tecken. ld a,c and 127 cp 127 ; Tecken < 32 och = 127 kod{ndras. jr z PCtrl cp 32 jr c PCtrl cp (ix+Qctl) ; Dessa tecken f|reg}as av Qctl men jr z PQctl ; kod{ndras inte. cp (ix+Qbin) jr z PQctl cp (ix+Rept) jr z PQctl jr PStoreChar PCtrl: ld a,c xor 64 ld c,a PQctl: ld a,(ix+Qctl) ld (de),a ; Lagra . inc de exx inc d ; \ka Utpos. exx PStoreChar: ld a,c ld (de),a ; Lagra tecknet. inc de exx inc d ; \ka Utpos. jr PLoop2