tcat wrote:Hi Per,
Xmas, Xpurposes, possibly?
Probably
I am not SMSQ/E owner and little would I know. My machine is QDOS v1.10 (JS-ROM), 2-MDs, 0-floppy, 0-HDD.
You could very easily be a proud SMSQ/E "owner" by downloading Marcel Kilgus'es excellent QPC2, and perhaps one of the beautiful distros currently available..
All the same, I wish to know what RLEx (=1,2,4) are, and how they differ to my code.
Many thanks
Tomas
Sorry, I forgot to reply to that one. RLE 1, 2, and 4 relate to the possible data sizes the inbuilt RLE decompressor works with. More detail may be found by following the link mk79 supplied in an earlier post here. However, the details arent quite clear to me by just reading that description, so to properly understand the workings of the format it is best to look at the source code. I hope Im doing no wrong by dropping the code here (the SMSQ/E license
applies!) I have slightly modified register usage and a few small steps, as I attached it to a S*BASIC keyword (all thats missing from this code is the initialisation code for one SB procedure):
Code: Select all
; Decompress RLE compressed data V1.00 ©2002 Marcel Kilgus
;
; Sandpit version - Wrapped for S*BASIC by pjw
section code
include dev8_keys_qlv
include dev8_keys_err
xdef derle
*
* Usage: DERLE source, target
*
* De-compresses a previously RLE-compressed data chunk
* The format of the compressed data chunk is:
* dc.l 'RLEx' with x = 1, 2, or 4
* dc.l uncompressed_size
* data
*
err_bp
moveq #err.ipar,d0
err_exit
rts
*
derle
move.w sb.gtlin,a2 get some longs
jsr (a2)
bne.s err_exit
subq.w #2,d3 only two wanted
bne.s err_bp
move.l 0(a6,a1.l),a2 -> compressed data header
move.l 4(a6,a1.l),a4 -> buffer of at least uncompressed data size
;+++
; Decompressed RLE compressed data
;
; RLE header: 0 'RLEx' with x either '1', '2' or '4' (item size in bytes)
; 4 size of uncompressed data
; 8+ compressed data
;
; Algorithm can work on an item size of byte, word and longword (s.above)
;
; The RLE data stream always consists of one byte and some items following.
; If the leading byte is in range of 0<=x<128 then x+1 uncompressed items
; are following the byte. Otherwise the next item is to be taken 257-x
; times.
;
; d0 r < 0 error, > 0 size of data
; a2 c p start of compressed data
; a4 cr address of buffer with uncompressed data
;---
regs reg d1-d2/a0/a2
pt_derle
movem.l regs,-(sp)
moveq #0,d2
move.l (a2)+,d1 ; ID
cmpi.l #'RLE1',d1
beq.s prle_rle
addq.w #2,d2
cmpi.l #'RLE2',d1
beq.s prle_rle
addq.w #2,d2
cmpi.l #'RLE4',d1
bne.s prle_norle
prle_rle
move.l a4,a0
move.l (a2)+,d1 ; uncompressed size
move.l d1,-(sp)
move.w pt_decomp(pc,d2.w),d2
jsr pt_decomp(pc,d2.w)
move.l (sp)+,d0 ; return size of data
prle_exit
movem.l (sp)+,regs
prle_norle
moveq #0,d0
rts
pt_decomp
dc.w prle_1-pt_decomp
dc.w prle_2-pt_decomp
dc.w prle_4-pt_decomp
; Uncompress byte sized data
prle1_loop
moveq #0,d0
move.b (a2)+,d0
bmi.s prle1_comp ; compressed data
sub.l d0,d1 ; subtract from total data size
bcs.s prle_rts ; emergency exit
subq.l #1,d1 ; it's x+1 actually
prle1_ucloop
move.b (a2)+,(a0)+ ; just copy uncompressed data
dbf d0,prle1_ucloop
bra.s prle_1
prle1_comp
move.l #257,d2
sub.l d0,d2
sub.l d2,d1 ; subtract from total size
bcs.s prle_rts ; emergency exit
subq.l #1,d2 ; dbf loop makes it one less
move.b (a2)+,d0
prle1_cloop
move.b d0,(a0)+ ; insert item d2 times
dbf d2,prle1_cloop
prle_1
tst.l d1
bhi.s prle1_loop
prle_rts
rts
; Uncompress 2 byte sized data
prle_2
lsr.l #1,d1 ; size in bytes -> size in items
bra.s prle2_start
prle2_loop
moveq #0,d0
move.b (a2)+,d0
bmi.s prle2_comp ; compressed data
sub.l d0,d1 ; subtract from total data size
bcs.s prle_rts ; emergency exit
subq.l #1,d1 ; it's x+1 actually
prle2_ucloop
move.w (a2)+,(a0)+ ; just copy uncompressed data
dbf d0,prle2_ucloop
bra.s prle2_start
prle2_comp
move.l #257,d2
sub.l d0,d2
sub.l d2,d1 ; subtract from total size
bcs.s prle_rts ; emergency exit
subq.l #1,d2 ; dbf loop makes it one less
move.w (a2)+,d0
prle2_cloop
move.w d0,(a0)+ ; insert item d2 times
dbf d2,prle2_cloop
prle2_start
tst.l d1
bhi.s prle2_loop
rts
; Uncompress 4 byte sized data
prle_4
lsr.l #2,d1 ; size in bytes -> size in items
bra.s prle4_start
prle4_loop
moveq #0,d0
move.b (a2)+,d0
bmi.s prle4_comp ; compressed data
sub.l d0,d1 ; subtract from total data size
bcs prle_rts ; emergency exit
subq.l #1,d1 ; it's x+1 actually
prle4_ucloop
move.l (a2)+,(a0)+ ; just copy uncompressed data
dbf d0,prle4_ucloop
bra.s prle4_start
prle4_comp
move.l #257,d2
sub.l d0,d2
sub.l d2,d1 ; subtract from total size
bcs prle_rts ; emergency exit
subq.l #1,d2 ; dbf loop makes it one less
move.l (a2)+,d0
prle4_cloop
move.l d0,(a0)+ ; insert item d2 times
dbf d2,prle4_cloop
prle4_start
tst.l d1
bhi.s prle4_loop
rts
*
end
It seems to me that while the decompressor can be a pretty mechanical affair, the compressor could do with some intelligence to improve on the degree of compression (eg a pair of identical adjacent items in a string of < 128 different items could be ignored, saving a byte for each occurrence)