home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
archives
/
luxorabc800.tar.gz
/
luxorabc800.tar
/
kermpack.asm
< prev
next >
Wrap
Assembly Source File
|
1990-07-08
|
14KB
|
345 lines
; 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 ; <Rept><Antal+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 <Qbin>.
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 <Qctl>.
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