home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / luxorabc800 / kermpack.asm < prev    next >
Assembly Source File  |  2020-01-01  |  14KB  |  345 lines

  1. ; Fil: KERMPACK.ASM
  2. ; Av:  Kristoffer Eriksson, "SKE" <5357>, 1987.
  3. ;
  4. ;-Ver--/-Datum----/-Sign-/-Kommentar----------------------------------
  5. ; 1.00 / 87-08-15 / SKE  / KERMPACK
  6. ;
  7. ; Packnings- och uppackningsrutiner till Bo Kullmars Kermit-program K.
  8.  
  9.  
  10. ;*  Packa upp buffert.
  11. ;*  In: DE pekare till inparametrar enligt:
  12.  
  13. UInbuff:    =  +0  ;W   Inbuffertens adress
  14. UInbuffs:   =  +2  ;B   Inbuffertens slutposition eller l{ngd-1 (0-255)
  15. UUtbuff:    =  +3  ;W   Utbuffertens adress
  16. UUtbuffl:   =  +5  ;B   Utbuffertens l{ngd i antal byte (94-255)
  17. Qctl:       =  +6  ;B   Tecken som markerar "tecken XOR 64"
  18. Qbin:       =  +7  ;B   Tecken som markerar "tecken OR 128"
  19. Rept:       =  +8  ;B   Tecken som markerar "tecken1-32 stycken tecken2"
  20.  
  21. ;*  In- och utbuffertarnas f|rsta byte anger n{sta oanv{nda position i resp
  22. ;*  buffert, r{knat med sig sj{lva som position noll. De uppdateras med
  23. ;*  aktuella v{rden vid retur.
  24. ;*
  25. ;*  Inbuffertens position kan bli upp till 5 h|gre {n dess slutposition,
  26. ;*  vilket inneb{r att om slutpositionen {r 251 eller mer kan man f|rlora
  27. ;*  positionens mest signifikanta bittar, varvid v{rdet blir 256 f|r l}gt.
  28. ;*  Detta beror p} att positionen bara kontrolleras mot l{ngden en g}ng f|r
  29. ;*  varje avkodat tecken, och varje tecken kan vara kodat med upp till 5 byte.
  30. ;*  [ven om bufferten bara inneh}ller korrekta koder, slutar positionen 1
  31. ;*  steg f|rbi slutpositionen (det blir ju f|rsta oanv{nda position), och
  32. ;*  {r l{ngden 255 blir det 0 som lagras som position.
  33. ;*
  34. ;*  Rutinen avbryts n{r n{sta inposition blir st|rre {n slutpositionen
  35. ;*  (Inpos > Inslut), eller det blir 93 eller f{rre tecken kvar i utbufferten
  36. ;*  (Utpos >= Utl{ngd - 93). Det senare vilkoret {r f|r att garantera att
  37. ;*  en Rept-sekvens f}r plats vid uppackning. Den kan bli max 94 tecken.
  38. ;*
  39. ;*  Rutinen returnerar i HL aktuell inposition - inl{ngden. Observera att
  40. ;*  h{r f|rlorar man inte n}gra signifikanta bittar i positionen.
  41. ;*
  42. ;*  Qctl, Qbin och Rept kan vara noll f|r att markera att de inte anv{nds.
  43.  
  44.  
  45. ; DE = Aktuell adress i utbuff, D' = Position i utbuff, E' = L{ngd av utbuff,
  46. ; HL = Aktuell adress i inbuff, BC' = Position i inbuff,
  47. ; B = Repetitionsfaktor, C = OR-faktor.
  48.  
  49. ; Inbuff-positionen ligger i ett dubbelregister eftersom den inte kontrolleras
  50. ; mot l{ngden vid varje |kning, och d{rf|r kan r}ka bli h|gre {n 255.
  51.  
  52. Unpbuff:    push   de
  53.             pop    ix
  54.             ld     l,(ix+UUtbuff)
  55.             ld     h,(ix+UUtbuff+1)
  56.             ld     c,(hl)
  57.             ld     b,0
  58.             add    hl,bc
  59.             ex     de,hl              ; DE <- Aktuell adress i utbuffert.
  60.             ld     a,c
  61.             exx
  62.             ld     d,a                ; D' <- Position i utbuffert.
  63.             ld     e,(ix+UUtbuffl)    ; E' <- Utbuffertens l{ngd.
  64.             exx
  65.  
  66.             ld     l,(ix+UInbuff)
  67.             ld     h,(ix+UInbuff+1)
  68.             ld     c,(hl)             ; (B = 0)
  69.             add    hl,bc              ; HL <- Aktuell adress i inbuffert.
  70.             push   bc
  71.             exx
  72.             pop    bc                 ; BC' <- Position i inbuffert.
  73.  
  74. ULoop:      ld     a,e
  75.             sub    94
  76.             cp     d                  ; J{mf|r  (E' - 94) med D'
  77.             jr c   UEnd               ; Avsluta om Utpos > Utl{ngd - 94.
  78.             ld     a,b
  79.             and    a
  80.             jr nz  UEnd               ; Inpos > 255, allts} Inpos > Inslut.
  81.             ld     a,(ix+UInbuffs)
  82.             cp     c
  83.             jr c   UEnd               ; Avsluta om Inpos > Inslut.
  84.  
  85. UCont:      inc    bc                 ; \ka Inpos i BC'.
  86.             exx
  87.             ld     a,(hl)             ; L{s Inbuffert och |ka Inadress.
  88.             inc    hl
  89.             ld     bc,1 << 8 + 0      ; B <- Reptfaktor 1, C <- OR-faktor 0.
  90.             and    a                  ; Ingen id` att j{mf|ra tecknet 0 med
  91.             jr z   UStoreChar         ; specialtecknen, f|r {r de noll
  92.                                       ; betyder det bara att de inte anv{nds.
  93. UchkRept:   cp     (ix+Rept)
  94.             jr nz  UchkQbin
  95.             ld     a,(hl)             ; H{mta n{sta byte = Repetitionsfaktor.
  96.             inc    hl
  97.             sub    32
  98.             cp     94
  99.             jr c   Ux1                ; A <- max(A,94). S{kerhetskontroll,
  100.             ld     a,94               ;            borde snarare meddela fel.
  101. Ux1:        ld     b,a                ; B <- Repetitionsfaktor.
  102.             ld     a,(hl)             ; A <- Repeterat tecken.
  103.             inc    hl
  104.             exx
  105.             inc    bc                 ; \ka Inpos.
  106.             inc    bc
  107.             exx
  108.  
  109. UchkQbin:   cp     (ix+Qbin)
  110.             jr nz  UchkQctl
  111.             ld     c,128              ; OR-faktor f|r teckenkod.
  112.             ld     a,(hl)             ; A <- P}verkat tecken.
  113.             inc    hl
  114.             exx
  115.             inc    bc                 ; \ka Inpos.
  116.             exx
  117.  
  118. UchkQctl:   cp     (ix+Qctl)
  119.             jr nz  UStoreChar
  120.             ld     a,(hl)             ; A <- P}verkat tecken.
  121.             inc    hl
  122.             exx
  123.             inc    bc                 ; \ka Inpos.
  124.             ld     l,a                ; L' <- A  (tempor{r lagring).
  125.             and    127
  126.             jr z   Ux2
  127.             cp     (ix+Rept)          ; S}lla bort tecken som inte p}verkas.
  128.             jr z   Ux3
  129.             cp     (ix+Qbin)
  130.             jr z   Ux3
  131.             cp     (ix+Qctl)
  132.             jr z   Ux3
  133. Ux2:        ld     a,l
  134.             xor    64
  135.             jr     Ux4
  136. Ux3:        ld     a,l
  137. Ux4:        exx
  138.  
  139. UStoreChar: or     c                  ; OR-faktor
  140. UStoreLoop: ld     (de),a             ; Lagra tecken i Utbuffert.
  141.             inc    de
  142.             exx
  143.             inc    d                  ; \ka Utpos.
  144.             exx
  145.             djnz   UStoreLoop         ; Repetitionsfaktor.
  146.  
  147.             exx
  148.             jr     ULoop
  149.  
  150. UEnd:       ld     l,(ix+UUtbuff)
  151.             ld     h,(ix+UUtbuff+1)
  152.             ld     (hl),d             ; (Utbuff) <- D' = Position i utbuffert.
  153.             ld     l,(ix+UInbuff)
  154.             ld     h,(ix+UInbuff+1)
  155.             ld     (hl),c             ; (Inbuff) <- BC' = Position i inbuffert.
  156.             ld     l,c
  157.             ld     h,b
  158.             ld     c,(ix+UInbuffs)
  159.             xor    a                  ; Nolla carry och A.
  160.             ld     b,a
  161.             sbc    hl,bc              ; Returv{rde HL <- Inposition - Inl{ngd.
  162.             ret
  163.  
  164.  
  165.  
  166. ;*  Packa buffert.
  167. ;*  In: DE pekare till inparametrar enligt:
  168.  
  169. PUtbuff:    =  +0  ;W   Inbuffertens adress
  170. PUtbuffl:   =  +2  ;B   Inbuffertens l{ngd i antal byte (10-255)
  171. PInbuff:    =  +3  ;W   Utbuffertens adress
  172. ReptPos:    =  +5  ;B   (Intern variabel, aktuell utpos vid start av rept.)
  173. ;Qctl:      =  +6  ;B   Tecken som markerar "tecken XOR 64"
  174. ;Qbin:      =  +7  ;B   Tecken som markerar "tecken OR 128"
  175. ;Rept:      =  +8  ;B   Tecken som markerar "tecken1-32 stycken tecken2"
  176.  
  177. ;*  In- och utbuffertarnas f|rsta byte anger n{sta oanv{nda position i resp
  178. ;*  buffert, r{knat med sig sj{lva som position noll. Dessa uppdateras med
  179. ;*  aktuella v{rden f|re retur. Inbuffertens andra byte anger dess l{ngd
  180. ;*  (0-255) i antal byte inklusive position och l{ngd-bytes.
  181. ;*
  182. ;*  Rutinen avbryts n{r det }terst}r nio eller f{rre tecken i utbufferten
  183. ;*  (Utpos >= Utl{ngd - 9) eller inbuffert {r slut (Inpos >= Inl{ngd).
  184. ;*  Marginalen i utbufferten {r till f|r att kodningen av n{sta tecken
  185. ;*  garanterat ska f} plats. Fast den {r on|digt stor, eftersom kodningen
  186. ;*  av ett tecken kan bli max 5 tecken.
  187. ;*
  188. ;*  Returnerar i HL -1 om aktuell inposition {r lika med inl{ngden, annars 0.
  189. ;*
  190. ;*  Qctl, Qbin och Rept kan vara noll f|r att markera att de inte anv{nds.
  191.  
  192. ; DE = Aktuell adress i utbuff, D' = Position i utbuff, E' = L{ngd av utbuff,
  193. ; HL = Aktuell adress i inbuff, B' = Position i inbuff, C' = L{ngd av inbuff,
  194. ; HL' = Adress i utbuff f|r ev repetionssekvens, B = Repetitionsr{knare.
  195.  
  196. Packbuff:   push   de
  197.             pop    ix
  198.             ld     l,(ix+PUtbuff)
  199.             ld     h,(ix+PUtbuff+1)
  200.             ld     c,(hl)             ; Position.
  201.             ld     b,0
  202.             add    hl,bc
  203.             ex     de,hl              ; DE <- Aktuell adress i utbuffert.
  204.             ld     a,c
  205.             exx
  206.             ld     d,a                ; D' <- Position i utbuffert.
  207.             ld     e,(ix+PUtbuffl)    ; E' <- Utbuffertens l{ngd.
  208.             exx
  209.  
  210.             ld     l,(ix+PInbuff)
  211.             ld     h,(ix+PInbuff+1)
  212.             ld     c,(hl)             ; Position.
  213.             inc    hl
  214.             ld     b,(hl)             ; L{ngd.
  215.             dec    hl
  216.             push   bc
  217.             ld     b,0
  218.             add    hl,bc              ; HL <- Aktuell adress i inbuffert.
  219.             exx
  220.             pop    hl
  221.             ld     b,l                ; B' <- Position i inbufferten.
  222.             ld     c,h                ; C' <- Inbuffertens l{ngd.
  223.                                       ; Repetitionsr{knaren B {r nu noll.
  224. PLoop:      ld     a,e
  225.             sub    10
  226.             cp     d                  ; J{mf|r  (E' - 10) med D'
  227.             jr c   PEnd               ; Avsluta om Utpos > Utl{ngd - 10.
  228.             ld     a,c
  229.             cp     b                  ; J{mf|r C' med B'.
  230.             jr z   PEnd
  231.             jr nc  PCont              ; Avsluta om Inpos >= Inl{ngd.
  232.  
  233. PEnd:       ld     l,(ix+PUtbuff)
  234.             ld     h,(ix+PUtbuff+1)
  235.             ld     (hl),d             ; (Utbuff) <- D' = Position i utbuffert.
  236.             ld     l,(ix+PInbuff)
  237.             ld     h,(ix+PInbuff+1)
  238.             ld     (hl),b             ; (Inbuff) <- B' = Position i inbuffert.
  239.             inc    hl
  240.             ld     (hl),c             ; (Inbuff+1) <- C' = L{ngd.
  241.             ld     a,b
  242.             cp     c
  243.             ld     hl,0
  244.             ret nz
  245.             dec    hl                 ; Returv{rde HL <- Inpos = Inl{ngd.
  246.             ret
  247.  
  248. PCont:      inc    b                  ; \ka Inpos i B' redan nu.
  249.             exx
  250.             ld     a,(ix+Rept)
  251.             and    a
  252.             jr z   PchkQbin           ; Ingen repetitionskomprimering.
  253.  
  254.             ld     a,(hl)             ; Aktuellt tecken.
  255.             dec    hl
  256.             cp     (hl)               ; J{mf|r tecknet med f|rra tecknet.
  257.             inc    hl
  258.             jr nz  PInitRept
  259.             inc    b                  ; \ka repetitionsr{knaren.
  260.             ld     a,b
  261.             cp     5
  262.             jr c   Px1                ; Hoppa om inte B > 4.
  263.             push   bc
  264.             ld     a,(ix+Rept)
  265.             exx
  266.             ld     (hl),a             ; Anv{nd den sparade utpekaren och
  267.             inc    hl                 ; {ndra i utbufferten till repetitions-
  268.             pop    af   ; A <- B = Rept.r{kn.                   sekvens med
  269.             add    32                 ; <Rept><Antal+32>, samt }terst{ll
  270.             ld     (hl),a             ; utadressen och utpositionen till
  271.             push   hl                 ; slutet av denna sekvens.
  272.             dec    hl
  273.             ld     d,(ix+ReptPos)
  274.             inc    d
  275.             inc    d
  276.             exx
  277.             pop    de
  278.             inc    de
  279.             cp     94+32              ; J{mf|r B med 94. (A {r nu B+32)
  280.             jr nz  PchkQbin
  281.             ld     b,0                ; Avbryt repeteringsbehandling efter
  282.             jr     PchkQbin           ; maxantalet 94 upprepningar.
  283.  
  284. PLoop2:     jr     PLoop              ; (F|r l}ngt f|r ett enda jr-hopp.)
  285.  
  286. Px1:        dec    a                  ; Om f|rra v{rdet p} rept-r{knaren var
  287.             jr nz  PchkQbin           ; noll, ska den startas om.
  288.  
  289. PInitRept:  ld     b,1                ; Tecknet {r inte likt f|reg}ende.
  290.             push   de                 ; Starta om repetitionsr{knare och
  291.             exx                       ; spara utadress och utposition.
  292.             pop    hl
  293.             ld     (ix+ReptPos),d
  294.             exx
  295.  
  296. PchkQbin:   ld     a,(hl)             ; Aktuellt tecken.
  297.             inc    hl                 ; Inbuffertadressen|kas f|rst nu.
  298.             ld     c,a
  299.             cp     128
  300.             jr c   PchkQctl           ; Behandla tecken >= 128 med Qbin
  301.             ld     a,(ix+Qbin)
  302.             and    a
  303.             jr z   PchkQctl           ; Avst{ngt.
  304.             ld     (de),a             ; Lagra <Qbin>.
  305.             inc    de
  306.             exx
  307.             inc    d                  ; \ka Utpos.
  308.             exx
  309.             ld     a,c
  310.             and    127                ; Nu slipper vi h|ga bitten.
  311.             ld     c,a
  312.  
  313. PchkQctl:   ld     a,(ix+Qctl)
  314.             and    a
  315.             jr z   PStoreChar         ; Ingen hantering av ctrl-tecken.
  316.             ld     a,c
  317.             and    127
  318.             cp     127                ; Tecken < 32 och = 127 kod{ndras.
  319.             jr z   PCtrl
  320.             cp     32
  321.             jr c   PCtrl
  322.             cp     (ix+Qctl)          ; Dessa tecken f|reg}as av Qctl men
  323.             jr z   PQctl              ; kod{ndras inte.
  324.             cp     (ix+Qbin)
  325.             jr z   PQctl
  326.             cp     (ix+Rept)
  327.             jr z   PQctl
  328.             jr     PStoreChar
  329. PCtrl:      ld     a,c
  330.             xor    64
  331.             ld     c,a
  332. PQctl:      ld     a,(ix+Qctl)
  333.             ld     (de),a             ; Lagra <Qctl>.
  334.             inc    de
  335.             exx
  336.             inc    d                  ; \ka Utpos.
  337.             exx
  338. PStoreChar: ld     a,c
  339.             ld     (de),a             ; Lagra tecknet.
  340.             inc    de
  341.             exx
  342.             inc    d                  ; \ka Utpos.
  343.  
  344.             jr     PLoop2
  345.