Skip to content

Commit

Permalink
Introduce Comper-X compression format and toolset.
Browse files Browse the repository at this point in the history
  • Loading branch information
vladikcomper authored and flamewing committed Jun 5, 2021
1 parent 4592f9a commit 59d8c3e
Show file tree
Hide file tree
Showing 5 changed files with 564 additions and 0 deletions.
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ endfunction()

define_lib(artc42 "src/lib/artc42.cc" "include/mdcomp/artc42.hh")
define_lib(comper "src/lib/comper.cc" "include/mdcomp/comper.hh")
define_lib(comperx "src/lib/comperx.cc" "include/mdcomp/comperx.hh")
define_lib(enigma "src/lib/enigma.cc" "include/mdcomp/enigma.hh")
define_lib(kosinski "src/lib/kosinski.cc" "include/mdcomp/kosinski.hh")
define_lib(kosplus "src/lib/kosplus.cc" "include/mdcomp/kosplus.hh")
Expand All @@ -315,6 +316,7 @@ define_lib(saxman "src/lib/saxman.cc" "include/mdcomp/saxman.hh")
define_lib(snkrle "src/lib/snkrle.cc" "include/mdcomp/snkrle.hh")

define_exe(compercmp "src/tools/compcmp.cc" comper compcmp)
define_exe(comperxcmp "src/tools/comperx.cc" comperx comperx)
define_exe(enigmacmp "src/tools/enicmp.cc" enigma enicmp)
define_exe(kosinskicmp "src/tools/koscmp.cc" kosinski koscmp)
define_exe(kospluscmp "src/tools/kosplus.cc" kosplus kosplus)
Expand All @@ -336,6 +338,7 @@ install(
bigendian_io
artc42
comper
comperx
enigma
kosinski
kosplus
Expand All @@ -345,6 +348,7 @@ install(
saxman
snkrle
compercmp
comperxcmp
enigmacmp
kosinskicmp
kospluscmp
Expand Down Expand Up @@ -372,6 +376,7 @@ export(
bigendian_io
artc42
comper
comperx
enigma
kosinski
kosplus
Expand Down
41 changes: 41 additions & 0 deletions include/mdcomp/comperx.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (C) Flamewing 2013-2016 <[email protected]>
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef LIB_COMPERX_HH
#define LIB_COMPERX_HH

#include <mdcomp/basic_decoder.hh>
#include <mdcomp/moduled_adaptor.hh>

#include <iosfwd>

class comperx;
using basic_comperx = BasicDecoder<comperx, PadMode::PadEven>;
using moduled_comperx = ModuledAdaptor<comperx, 4096U, 1U>;

class comperx : public basic_comperx, public moduled_comperx {
friend basic_comperx;
friend moduled_comperx;
static bool encode(std::ostream& Dst, uint8_t const* data, size_t Size);

public:
using basic_comperx::encode;
static bool decode(std::istream& Src, std::iostream& Dst);
};

#endif // LIB_COMPERX_HH
142 changes: 142 additions & 0 deletions src/asm/ComperX.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
; -----------------------------------------------------------------------------
; Comper-X a newer, much faster implementation of Comper compression
;
; (c) 2021, vladikcomper
; -----------------------------------------------------------------------------
; Permission to use, copy, modify, and/or distribute this software for any
; purpose with or without fee is hereby granted.
;
; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
; OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
; -----------------------------------------------------------------------------
; INPUT:
; a0 - Source Offset
; a1 - Destination Offset
;
; USES:
; d0-d4, a2
; -----------------------------------------------------------------------------

; -----------------------------------------------------------------------------
; Copy device for RLE transfers
;
; This is located above the compressor for accesibility reasons.
; -----------------------------------------------------------------------------

rts ; copy length = 0 stops decompression
rept 127
move.l d4, (a1)+
endm
ComperXDec_CopyDevice_RLE:
dbf d3, ComperXDec.fetch_flag ; if bits counter remains, parse the next word
;bra ComperXDec.load_flags_field ; ... fall through ...

; -----------------------------------------------------------------------------
; Decompressor starts here ...
; -----------------------------------------------------------------------------

ComperXDec:
moveq #-1, d1 ; d1 is used for negative sign-extended displacement
moveq #0, d2 ; d2 is used as 8-bit index for copy jump tables

.load_flags_field:
moveq #16-1, d3 ; d3 = description field bits counter
move.w (a0)+, d0 ; d0 = description field data

.fetch_flag:
add.w d0, d0 ; roll description field
bcs.s .flag ; if a flag issued, branch
move.w (a0)+, (a1)+ ; otherwise, do uncompressed data

.flag_next:
dbf d3, .fetch_flag ; if bits counter remains, parse the next word
bra.s .load_flags_field ; start a new block

; -----------------------------------------------------------------------------
.end rts

; -----------------------------------------------------------------------------
.flag: move.b (a0)+, d1 ; d1 = Displacement (words) (sign-extended)
beq.s .copy_rle ; displacement value of 0 (-1) triggers RLE mode
move.b (a0)+, d2 ; d2 = Copy length field

add.w d1, d1 ; d1 = Displacement * 2 (sign-extended)
lea -2(a1,d1.w), a2 ; a2 = Start copy address

moveq #-1, d1 ; restore the value of d1 now ...

add.b d2, d2 ; test MSB of copy length field ...
bcc.s .copy_long_start ; if not set, then transfer is even words, branch ...
move.w (a2)+, (a1)+ ; otherwise, copy odd word before falling into longwords loop ...

.copy_long_start:
jmp ComperXDec_CopyDevice(pc,d2.w) ; d2 = 0..$FE

; -----------------------------------------------------------------------------
.copy_rle:
move.b (a0)+, d1 ; d1 = - $100 + Copy length

move.w -(a1), d4
swap d4
move.w (a1)+, d4 ; d4 = data to copy

add.b d1, d1 ; test MSB of copy length field ...
bcc.s .copy_long_rle_start ; if not set, then transfer is even words, branch ...
move.w d4, (a1)+ ; otherwise, copy odd word before falling into longwords loop ...

.copy_long_rle_start:
jmp ComperXDec_CopyDevice_RLE(pc,d1.w) ; d1 = -$100..-2

; -----------------------------------------------------------------------------
; Copy device for RLE transfers
;
; This is located below the compressor for accesibility reasons.
; -----------------------------------------------------------------------------

ComperXDec_CopyDevice:
rts ; copy length = 0 stops decompression
rept 127
move.l (a2)+, (a1)+
endm
dbf d3, ComperXDec.fetch_flag ; if bits counter remains, parse the next word
bra ComperXDec.load_flags_field

; =============================================================================









; =============================================================================
; -----------------------------------------------------------------------------
; Subroutine to decompress Moduled Comper-X
; -----------------------------------------------------------------------------
; INPUT:
; a0 - Source Offset
; a1 - Destination buffer
; -----------------------------------------------------------------------------

ComperXMDec:
lea ComperXDec(pc), a3

move.w (a0)+, d0
subq.w #1, d0 ; this is a trick to reduce number of blocks by one if size is modulo $1000
rol.w #5, d0
and.w #$1E, d0 ; d0 = Number of blocks to decompress * 2 (0..1E)
neg.w d0
jmp .decompress_device(pc,d0)

rept 16-1
jsr (a3)
endm
.decompress_device:
jmp (a3)
Loading

0 comments on commit 59d8c3e

Please sign in to comment.