Hi all! :-[
Please forgive even more of my petty ignorance!
I've been trying to get my head around this for a while now and I have to give up and admit I need help... again!
When I add some .pck files (created with BITBuster 1.2 on a PC) to my .dsk in WinAPE 2A18 they come up as Unknown ASCII/Binary files and, therefore, refuse to load directly into CPC memory; is there an easy way to get these files to show as Binary?
Thanks again,
- JTMS...
Have you ticked the 'Add/Remove AMSDOS headers' option in the WinAPE Disc Editor before you copy the file into the DSK from your PC...?
Quote from: redbox on 12:48, 28 September 11
Have you ticked the 'Add/Remove AMSDOS headers' option in the WinAPE Disc Editor before you copy the file into the DSK from your PC...?
Ah ha! Top stuff!! Thank you!
Quote from: tastefulmrship on 13:07, 28 September 11
Ah ha! Top stuff!! Thank you!
Np - I make that mistake all the time :)
Funny to see we're both playing with crunchers today.
Do you have a link to the Bit Buster PC program and CPC decruncher routine?
Quote from: redbox on 13:10, 28 September 11
Do you have a link to the Bit Buster PC program and CPC decruncher routine?
Here is the one I'm using at the moment; http://cpcrulez.fr/applications_tools_cruncher_bitbuster_Z80.htm (http://cpcrulez.fr/applications_tools_cruncher_bitbuster_Z80.htm)
However, I'm finding that I cannot resolve back to BASIC (or any other MC routine)... it must be something I've done.
Quote from: tastefulmrship on 13:14, 28 September 11
However, I'm finding that I cannot resolve back to BASIC (or any other MC routine)... it must be something I've done.
Well if you want to use it under BASIC it says in the source "You must save secondary registers if you want to use the routine under Basic." - but calling routine
main (at beginning, being &A000) does this for you. Of course you'll need to change the source (set to &4000) and destination (set to &C000) in main to where your code is and you want it to be depacked to before you compile the binary.
If you want to use it in MC, then just
LD HL,source:LD DE,destination and
CALL depack. Assume most registers are destroyed I expect.
It does pack quite nicely, but not quite as well as Exomizer though.
Er, yeah.
Caught in an infinite loop it appears...
Use exomizer 8)
The problem was the source files still had AMSDOS headers... and BITBuster doesn't really like AMSDOS headers!
I re-packed the headerless files and all is fine!
I've had differing results with all crossdev packers; there doesn't seem to be a 'best of', as it depends on the source file itself as to which packer results in the smallest file. Sometimes PUCruncher is better, sometimes Exomiser and so on. It's personal taste, I guess. BITBuster does the job perfectly for me.
EDIT:
Quote from: redbox on 13:38, 28 September 11
Er, yeah.
Caught in an infinite loop it appears...
Use exomizer 8)
Use headerless source files! Tick that AMSDOS header button before copying to PC.
Quote from: tastefulmrship on 13:40, 28 September 11
The problem was the source files still had AMSDOS headers... and BITBuster doesn't really like AMSDOS headers!
Hahahahaha, that's funny considering how the thread started! Nice find though.
Quote from: tastefulmrship on 13:40, 28 September 11
I've had differing results with all crossdev packers; there doesn't seem to be a 'best of', as it depends on the source file itself as to which packer results in the smallest file. Sometimes PUCruncher is better, sometimes Exomiser and so on. It's personal taste, I guess. BITBuster does the job perfectly for me.
I agree, depends on the situation. And exomizer requires a buffer which some others don't.
I'm writing some new software with lots of crunchers in though, so I'll include PUCrunch and BitBuster now.
Have you ever compared CPCT aginst PC crunchers? My experiences with CPCT are very good. Thank's Madram!
Quote from: TFM/FS on 16:35, 28 September 11
Have you ever compared CPCT aginst PC crunchers? My experiences with CPCT are very good. Thank's Madram!
In my opinion, CPCT is one of the best native CPC crunchers, but compression is very slow indeed, even on a CPC emulator with the speed set to maximum. The likes of Exomizer and MegaLZ offer much better compression than CPCT and have the advantage of very fast compression - but on the other hand, CPCT's decompression routines are
much faster than Exomizer and MegaLZ.
I really ought to write a CPCWiki article on how to use Exomizer with a CPC... ::)
An article would be great!
How much better is exomizer compared to CPCT when looking at file-size?
Excuse my words, but I don't even give a crap on compression time. That's what I do once in a lifetime for a a given version of a program. So I can wait that minute (especially when using an emulator).
But what really matters is (aside of the size of the compressed file) the DEcompression time, because I will have to wait for the decompression every time I want to use the program. And if CPCT is better there (wow!). Unexpected, but that kick's PC-butts ;-)
However, if the filesize of a exomizer-compressed file is way better that other crunchers, that I wouldn't mind to wait 2 seconds longer for decompression. However a difference between 12 KB and 15 Kb wouldn't be an argmument for me.
I don't have exomizer, bitbuster and all that stuff, but it would be interesting to have some tables to compare their compression rate :-)
Quote from: TFM/FS on 21:17, 09 October 11
An article would be great!
Agreed. Something to remember when using Exomizer is that the input has to be in lowercase, and not uppercase as shown in all the documentation. So for example, the correct way to use it on your PC is:
exomizer raw filename.bin
and not
EXOMIZER RAW FILENAME.BIN
Took me a while to work out why it wasn't working when I was using it ;)
Quote from: TFM/FS on 21:17, 09 October 11
I don't have exomizer, bitbuster and all that stuff, but it would be interesting to have some tables to compare their compression rate :-)
See here for a comparison: http://cpcrulez.fr/applications_tools_cruncher_COMPARATIF.htm (http://cpcrulez.fr/applications_tools_cruncher_COMPARATIF.htm)
Yes, thank's I saw that before, but ... it's French! :-X
Ich finde deutschen einfacher als franzosisch, es ist wahr...
Aber franzosisch ist wirklich nicht zu hart TFM!
Original &7025
CPC_T v3.0 Beta 1 &35D4
Exomizer v2.0 beta 6 &2AD5
French and Spanish are the most beautiful languages in the world.
To learn German must be a pain in the arse back. However even I can do a bit in English, and if I wouldn't have that pain in the head (no I had no alcolhol for 5 weeks!), I probably would get along with French better.
I found German much easier than French. German generally sticks to the rules, French just breaks them all the time.
Exomizer does crunch an amazing amount, but I have heard of problems with decompression sometimes. It has been used a lot though, Fano uses it in the new R-Type and Axelay mentions using it a lot. SyX talked to me about compressors and he has found mixed results too.
But, as you say, it is all down to personal choice and thankfully there are a lot of options so you can see which one fits best in each situation. Like you say, it's not always about the compression but sometimes about how fast decompression is etc.
Rather than a Wiki article about just Exomizer, it would be nice to see one about Crunchers in general which weighs up the pros and cons of each one.
Apropos of compressor (the Babel subject is other world, jejejeje, and wait to add the dialects to the discussion ;) ), i don't trust in exomizer, i have used in a few projects without problems even in backward mode, but i have crunched a few files that the z80 decruncher can not decrunch and passed a lot of time debugging my code :-[
Because that, now i use aplib exclusively, the decruncher is short (only 163 bytes, while exomizer are 191 bytes + 156 bytes for the table exo_mapbasebits) and noticebly faster than exomizer, but exomizer crunch better.
Another great thing with aplib is that i can decrunch in place easily, loading the file at the end of destination ram zone with only a clearance of 16 bytes (SOURCE_ADDRESS + LEN_DECRUNCH_FILE - LEN_CRUNCH_FILE + 16), normally is 3 ó 4 bytes, but with 16 i'm completely sure :) Although i would like it was possible to decrunch through $FFFF, because in Renegade i have a hollow of a few hundreds of bytes where put my code in $8000, and i would be nice make a big file from $8200 - $8000, instead of making two files ($0000-$8000 / $8200-$FFFF).
I have studied a few Z80 decrunchers from zx, msx, master system, gb, ... and a few 68000 decrunchers, i have converted packfire (http://www.pouet.net/prod.php?which=54840) tiny mode to z80, and how aplib, it doesn't need a buffer in ram how exomizer (the table is in the first 26 bytes of every crunched file) and the decrunched files are the same size that exomizer (or even a few bytes smaller), but is much much more slower and the tiny mode only can compress up 32 KBs, not a single byte more.
I have used the table and files that appears in MegaLZ Benchmarks (http://lvd.nm.ru/MegaLZ/) and i have updated with these 3 compressors, plus ZIP and 7Z to compare them with modern compressors.(*) Table update in my next post
And i'm going to attach my packfire tiny decruncher, feel free to optimize, it's so slowwwwww :P ; ---------------------------------------------------------------------------
; Packfire tiny decruncher for Z80 by Syx 2011
; Original MC68000 code by Franck "hitchhikr" Charlet
; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
; packfire_decrunch: HL = Source / DE = Destination
; ---------------------------------------------------------------------------
packfire_decrunch
PUSH HL
POP IX ; IX = tabla de frecuencias
LD BC,26
ADD HL,BC ; HL = Crunch data
LD A,(HL) ; Initilize bit counter (A)
INC HL
literal_copy
LDI
main_loop
CALL get_bit
JR C,literal_copy
LD IYL,$FF
get_index
INC IYL
CALL get_bit
JR NC,get_index
EX AF,AF'
LD A,IYL
CP $10
RET Z ; Decrunch finish
EX AF,AF'
CALL get_pair ; Before the CALL IY < 256 always, after return can be IY > 255
LD (sm_len + 1),IY ; Bytes to copy *** IY > 255 ***
EX AF,AF'
LD A,IYL
CP 3
JR NC,es_mayor_2
DEC A
JR Z,es_1
DEC A
JR NZ,es_0
es_2
LD A,$04 ; table_len[2]
LD BC,$0020 ; table_dist[2]
JR fin_cmp
es_1
LD A,$02 ; table_len[1]
LD BC,$0030 ; table_dist[1]
JR fin_cmp
es_0
es_mayor_2
LD A,$04 ; table_len[0]
LD BC,$0010 ; table_dist[0]
fin_cmp
LD (sm_d0 + 1),BC
LD B,A
EX AF,AF'
CALL get_bits
CALL get_pair
PUSH HL
LD H,D
LD L,E ; A3 = A1
LD B,IYH
LD C,IYL ; BC = D3
OR A ; Clear Carry
SBC HL,BC
sm_len
LD BC,$0000 ; Can be > 255
LDIR
POP HL
JR main_loop
; -------------------------------------------------------------------------------------------------
; Used Registers A (D7), DE (A1), HL (A2), IX (A0)
; Free Register BC, A', BC', DE', HL'
get_pair
EX AF,AF'
EXX
INC IYL ; Here IY < 256 always
LD C,0 ; A6 = 0.L
calc_len_dist
LD A,C ; D0 = A6.W
AND $0F ; D0 &= $0F
JR NZ,node ; IF D0 == $x0 THEN D5 = 1.W
LD HL,1 ; D5 = 1.W
node
LD D,A ; Save for the BIT
LD A,C ; D4 = A6.W (A6 <= 52 .B)
RRA ; D4 >> 1
LD (sm_ix + 2),A
sm_ix
LD A,(IX + 0) ; D1 = A0[D4].B (A0 => IX | D4 <= 26)
BIT 0,D ; D4 = 1 | D0 &=D4 =>D0 &= 1 (Because D0 is changed next)
JR Z,nibble ; Use low nibble
RRA
RRA
RRA
RRA ; D1 >> 4 use high nibble (nibble alternating)
nibble
AND $0F ; D1 &= $0F
LD B,A ; D1 must go in register B for get_bits
LD (sm_d0 + 1),HL ; D0 = D5.W (In the last pass has the value for sm_d0)
; 1 << D1 (D1 = $0 - $F)
LD DE,$0000
CP 8
JR C,ponlo_en_e
ponlo_en_d
SUB 8
OR %01011000
JR sigue_generando_el_set
ponlo_en_e
OR %01111000
sigue_generando_el_set
RLCA
RLCA
RLCA
LD (sm_set + 1),A
sm_set
SET 0,A ; Transform in SET x,D or SET x,E
ADD HL,DE ; D5 += D4.L
INC C ; A6++
DEC IYL ; D3--
JR NZ,calc_len_dist
LD A,B
EXX
LD B,A
EX AF,AF'
get_bits
LD IY,0
INC B
getting_bits
DJNZ cont_get_bits
sm_d0
LD BC,$0000
ADD IY,BC
RET
cont_get_bits
CALL get_bit
; Simulate ADC IY,IY
JR NC,solo_duplica_iy
ADD IY,IY
INC IY ; It looks that INC IYL works fine
JR getting_bits
solo_duplica_iy
ADD IY,IY
JR getting_bits
; ---------------------------------------------------------------------------
get_bit
ADD A,A
RET NZ
LD A,(HL)
INC HL
ADC A,A
RET
Thank you so much SyX!!! This is alrady a complete wiki article :-)))
Well, we would need to add the results with CPCT and others CPC native crunchers and then we will have the article :)
If you want TFM, i can do it, but tell me what CPC compressors i should test ;)
Quote from: SyX on 21:13, 10 October 11
Well, we would need to add the results with CPCT and others CPC native crunchers and then we will have the article :)
If you want TFM, i can do it, but tell me what CPC compressors i should test ;)
Well, in case we take the French site in account then CPCT and the latest Cheese would be enought I guess. But we can just copy-paste-steal the results from them ;-)
@SyX: Thanks for your great effort to create a kind of benchmark :)! Btw, maybe CPCAlive (http://www.cpcalive.com/cpcalive_en.html (http://www.cpcalive.com/cpcalive_en.html) - this page is a bit strange...) can help you with testing the CPC cruncher, because it should be possible to use and control CPCAlive directly from the command line and also use files on the harddisk. Maybe you can create a kind of batch file to test the CPC compressors with it.
Thanks Octoate, although i have used WinApe for it... the most boring was waiting to the crunchers finish its task even using the Full Speed/Frame Skip 50/Fast Disk Access (my netbook is guilty :P ), than prepare the DSK with the files (that is automatized by a shell script).
All the files crunched are 1,2 Megabytes, if somebody want them, only ask ;)
And the table update with the native CPC crunchers is: | SIZE|MegaLZ|BITBUS|HRUS21|PCD6.2|RIP.01|CHEESE|CPCT31| CROWN| APLIB| EXO|PFIREt| PFIRE| ZIP| 7Z
-------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------
code-1 | 27932| 12654| 12827| 12865| 12904| 12118| 15771| 14262| 16558| 12222| 12207| 12215| 10833| 12680| 11155
code-2 | 14807| 7767| 8119| 8012| 8090| 7689| 10094| 9510| 11935| 7802| 7597| 7597| 7149| 7904| 7367
code-3 | 35840| 8406| 8181| 8291| 8373| 7891| 10785| 10179| 10772| 7964| 7810| (1)| 6302| 8667| 6542
-------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------
scrv-1 | 6912| 4672| 4757| 4705| 4764| 4551| 5219| 5104| 5250| 4692| 4568| 4568| 4430| 4687| 4455
scrv-2 | 6912| 4074| 4170| 4144| 4173| 4030| 4691| 4802| 5317| 4116| 3971| 3970| 3901| 4228| 3980
scrv-3 | 6912| 3604| 3717| 3722| 3753| 3544| 4174| 4273| 4854| 3677| 3517| 3516| 3370| 3679| 3448
scrv-4 | 6912| 2211| 2270| 2359| 2366| 2165| 2783| 2696| 3697| 2228| 2063| 2063| 2008| 2301| 2121
scrv-5 | 6912| 4399| 4470| 4486| 4524| 4298| 5050| 5048| 5558| 4421| 4249| 4249| 4158| 4476| 4173
scrv-6 | 6912| 4233| 4300| 4345| 4364| 4129| 4873| 5084| 5634| 4291| 4093| 4093| 4053| 4297| 4086
scrv-7 | 6912| 3788| 3902| 3921| 3942| 3721| 4534| 4512| 5468| 3800| 3625| 3625| 3506| 3878| 3624
scrv-8 | 6912| 5275| 5345| 5308| 5373| 5139| 5928| 5888| 6480| 5305| 5080| 5088| 4994| 5015| 5344
scrv-9 | 6912| 4958| 5081| 5048| 5095| 4844| 5677| 5732| 6285| 5031| 4818| 4818| 4673| 5035| 4752
-------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------
text-1 | 6859| 3858| 4077| 4004| 4029| 3726| 5084| 4963| 6133| 3946| 3794| 3794| 3595| 3857| 3751
text-2 | 21746| 7341| 7766| 7549| 7470| 6525| 12202| 8178| 11223| 6878| 6584| 6584| 6047| 6642| 6175
text-3 | 28352| 10252| 11156| 10360| 10246| 8847| 17537| 11304| 15258| 9383| 8990| 8990| 8241| 8955| 8365
text-4 | 39159| 20406| 22246| 20892| 20752| 17334| (2)| 23343| 30728| 19247| 17830| (1)| 16451| 17534| 16584
text-5 | 25149| 10443| 11225| 10618| 10515| 9088| 15998| 11754| 16359| 9712| 9293| 9292| 8554| 9236| 8627
(1) Original file is bigger 32KBs, PackFire tiny doesn't compress
(2) Original file is bigger 38KBs, Cheese Cruncher doesn't compress
NOTES:
.- The CPC native crunchers are "Cheese Cruncher v2.2", "CPCT v3.1" and "Crown Cruncher v1.4".
.- All the files sizes are without Amsdos headers.
.- PFIREt is PackFire tiny mode and PFIRE is PackFire normal mode.
.- There is not CPC decruncher for ZIP, 7Z and PackFire normal mode.
It's not a surprise that the cross-platform crunchers (all based in LZ or Huffman algorythms, technology more known in the internet era) are better (not faster although aplib has a faster decruncher) than the native crunchers (normally RLE and similar technology well known in the 80s).
This is great work Syx.
Packfire rulez! Just need to optimise and it's a real Exomizer beater.
What were you doing with Renegade?
Thank's a lot SyX - great work!!! :) :) :)
So... the best PC cruncher is "just" 25% better than the best CPC cruncher. Actually not really much. But once a while it will be needed :-)))
@Syx
Lots of great stuff to think about, thanks!
Out of interest, which version of Packfire were you using? Was it the v1.2h release?
EDIT: Using 1.2g, my two test screens (AMPSKULL.SCR & MASKFACE.SCR) do pack better with PackFire than all of the other external packers. Is there a Z80 decompressor available yet?
SyX provided his port of the Packfire decompressor in his post...
Quote from: redbox on 18:05, 11 October 11
SyX provided his port of the Packfire decompressor in his post...
Yeah, I guess that's my dumb-move-of-the-day! I even had it in an assembler window in WinAPE!
As the modern philosopher, Homer, would say; "D'oh!"
Quote from: redbox on 14:27, 11 October 11Packfire rulez! Just need to optimise and it's a real Exomizer beater.
Although that is not an esay task, jejeje, PF is designed to make great use of the 68000 registers and addressing modes by one of the best 68000 assembly coders. He help me to optimize my aplib port to 68000 and we were able to shrink at 164 bytes, only one byte more than the z80 version and we're talking of a cpu with the opcodes of a double size in bytes minimum.
Quote from: redbox on 14:27, 11 October 11What were you doing with Renegade?
I had patched to use the 3 fire buttons joystick that i made a few weeks ago, you can find here (http://www.amstrad.es/forum/viewtopic.php?f=3&t=2498) ;)
Quote from: TFM/FS on 16:21, 11 October 11So... the best PC cruncher is "just" 25% better than the best CPC cruncher. Actually not really much. But once a while it will be needed :-)))
And if you need help to adding at one of your projects only tell me ;)
Jejeje, you know how i'm old school for a few things (the config of my text editor has not changed since the cygnus editor days :P ) and new school for all my cross developing tools, jejeje.
Quote from: tastefulmrship on 16:58, 11 October 11Out of interest, which version of Packfire were you using? Was it the v1.2h release?
I'm using the last version (1.2h), but the sources of the decruncher has not changed from a few versions ago, only the cruncher to improve the compression and fix bugs ;)
Quote from: tastefulmrship on 16:58, 11 October 11EDIT: Using 1.2g, my two test screens (AMPSKULL.SCR & MASKFACE.SCR) do pack better with PackFire than all of the other external packers. Is there a Z80 decompressor available yet?
Remember that i only have converted the tiny mode (params -t when you are crunching and with that the crunched sizes are similar to exomizer). I didn't convert the large mode (is a variant of LZMA (http://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Markov_chain_algorithm), tiny is a LZ (http://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv) how aplib and exomizer) because it would be so slow that it would not had practical use in CPC... it's even slow in 68000 and there, it's using every trick in the hat.
Missed your Renegade patch SyX - very nice though. Didn't realise Amstrad.es has a forum, I need to learn Spanish now (I have been trying French but that is hard, so maybe Spanish will be a nice diversion!).
I love compression because it's real uber programming and maths. The Packfire compressor and decompressor is very exciting, think I'll take a look through your source and try and see what's going on because for once hopefully I'll understand it because it's in Z80 :)
Quote from: redbox on 19:00, 11 October 11Missed your Renegade patch SyX - very nice though. Didn't realise Amstrad.es has a forum, I need to learn Spanish now (I have been trying French but that is hard, so maybe Spanish will be a nice diversion!).
Everybody is welcome at the spanish forum, it's full of great content and we don't bite at people talking in other languages :P
Totally agreed, learn a new language is always FUN :)
Quote from: redbox on 19:00, 11 October 11I love compression because it's real uber programming and maths. The Packfire compressor and decompressor is very exciting, think I'll take a look through your source and try and see what's going on because for once hopefully I'll understand it because it's in Z80 :)
I usually convert or make a compressor to get familiar with a new CPU (my last was convert aplib to 6800, for a Dragon project :) ), because you need to use a great part of the instruction set, it's a much better "hello world" program ;D
Here is the original 68000 source "hypercomented" (in spanish sorry), you can use to understand better how i converted it:
; ------------------------------------------
; PackFire 1.2f - (tiny depacker)
; ------------------------------------------
; ------------------------------------------
; packed data in a0 ; A0 = Origen (se usa como puntero a
; la tabla de frecuencias)
; dest in a1 ; A1 = Destino
start: lea 26(a0),a2 ; A2 = A0 + 26 <- Datos comprimidos
move.b (a2)+,d7 ; D7.B = (A2) <- 1º Byte comprimido
; A2++
; Se inicializa el contador de bits
lit_copy: move.b (a2)+,(a1)+ ; (A1).B = (A2).B <- Copiamos byte
; A1++
; A2++
main_loop: bsr.b get_bit ; CALL get_bit <- .B un salto corto
bcs.b lit_copy ; JR C,lit_copy <- CS Carry Set
; Este último trozo lo que hace es
; que mientras se obtengan bits a
; 1, iremos copiando bytes de forma
; literal.
moveq #-1,d3 ; D3.L = $FFFFFFFF
get_index: addq.l #1,d3 ; D3++
bsr.b get_bit ; CALL get_bit
bcc.b get_index ; JR NC,get_index <- CC Carry Clear
cmp.w #$10,d3 ; ¿D3 == $0010?
beq.b depack_stop ; JR Z,depack_stop
; Se acabó la descompresión
bsr.b get_pair ; CALL get_pair
move.w d3,d6 ; D6.W = D3.W <- Lo guarda para
; usarlo como contador en copy_bytes
cmp.w #2,d3 ; ¿D3 == $0002?
ble.b out_of_range ; JR <=,out_of_range
; <- LE Less or equal
moveq #0,d3 ; D3.L = 0
; En estás 3 últimas líneas lo que
; hacen es si D3 > 2, entonces D3=0
out_of_range: moveq #0,d0 ; D0.l = 0
move.b table_len(pc,d3.w),d1 ; D1.B = table_len[D3.W]
move.b table_dist(pc,d3.w),d0 ; D0.B = table_dist[D3.W]
bsr.b get_bits ; CALL get_bits
bsr.b get_pair ; CALL get_pair
; Se obtiene el offset y la longitud
; de la cadena de bytes ya
; descomprimida que se va a copiar
; a continuación.
move.l a1,a3 ; A3.L = A1.L
sub.l d3,a3 ; A3.L -= D3.L
copy_bytes: move.b (a3)+,(a1)+ ; (A1).B = (A3).B
; A3++
; A1++
subq.w #1,d6 ; D6.W--
bne.b copy_bytes ; JR NZ,copy_bytes <- ¿D6 == 0?
bra.b main_loop ; JR main_loop
table_len: dc.b $04,$02,$04
table_dist: dc.b $10,$30,$20
get_pair: sub.l a6,a6 ; A6.L = 0
moveq #$f,d2 ; D2.L = $0000000F <- D2 es constante
calc_len_dist: move.w a6,d0 ; D0.W = A6.W
and.w d2,d0 ; D0.W &= D2.W <- D0.W 0-$F
bne.b node ; JR NZ,node
moveq #1,d5 ; D5.L = 1
node: move.w a6,d4 ; D4.W = A6.W
lsr.w #1,d4 ; D4.W >> 1
move.b (a0,d4.w),d1 ; D1 = A0[D4.W] <- Se lee un byte
; de la tabla de frecuencias, por lo
; que D4 < 26 ó lo que es lo mismo
; A6 < 26 * 2, lo cual nos
; permitirá usar un registro de 8
; bits del Z80.
;
moveq #1,d4 ; D4.L = 1
and.w d4,d0 ; D0.W &= D4.W <- D0.W &= 1
beq.b nibble ; JR NZ,nibble
; Podemos sustituir las tres últimas
; instrucciones por:
; BIT 0,D0 / JR Z,nibble
lsr.b #4,d1 ; D1.B >> 4
; Lo que se ha hecho es seleccionar
; entre el nibble de más peso ó
; menos peso del byte leido de la
; tabla de frecuencias (así que mas
; que 26 bytes, son 52 nibbles), y ; se realiza de forma alternativa,
; empezando por el bajo.
nibble: move.w d5,d0 ; D0.W = D5.W
and.w d2,d1 ; D1.W &= $F <- D1.W 0-$F
; nos quedamos solo con el nibble
lsl.l d1,d4 ; D4.L << D1 <- 1 << D1
; D4 = 2^D1 <- 1 - 32768
add.l d4,d5 ; D5.L += D4.L
addq.w #1,a6 ; D6.W++
; Recordar que D6 < 26 * 2
dbf d3,calc_len_dist ; D3.W--
; ¿D3 == $FFFF?
; JR NZ,calc_len_dist
; En el 68000, su DJNZ es hasta -1
; en lugar de a 0, como en el Z80.
get_bits: moveq #0,d3 ; D3.L = 0
getting_bits: subq.b #1,d1 ; D1.B--
bhs.b cont_get_bit ; JR NC,cont_get_bit <- HS = CC
add.w d0,d3 ; D3.W += D0.W
depack_stop: rts ; RET <- Por aquí se sale también
cont_get_bit: bsr.b get_bit ; CALL get_bit
addx.l d3,d3 ; D3 = D3 * 2 + Carry
; En el registro de estado del 68000
; a parte del Acarreo, hay una
; bandera X (eXtended) que se usa
; como bit de más peso en las
; operaciones matemáticas, aunque
; normalmente es una copia del
; Acarreo, como en este caso, no
; siempre lo es.
bra.b getting_bits ; JR getting_bits
get_bit: add.b d7,d7 ; D7 << 1
bne.b byte_done ; JR NZ,byte_done <- RET NZ
move.b (a2)+,d7 ; D7.B = (A2)
; A2++
addx.b d7,d7 ; D7 = D7 * 2 + Carry
byte_done: rts ; RET
; Esta es la típica rutina para
; extraer bits de los datos
; comprimidos.
Quote from: Nich on 11:45, 09 October 11
I really ought to write a CPCWiki article on how to use Exomizer with a CPC... ::)
I've done it (http://cpcwiki.eu/index.php/Exomizer)! :D It's rather verbose, and it assumes that you are using a Windows machine (sorry, Linux users! ;)), and there are still some things I want to add to the article, such as how to use backwards compression. I also want to provide a version of the decompression routines that actually work with
WinAPE without having to make significant corrections to it. Let me know what you think of the article!
It looks Great Nich!!! :D
I think is perfect for everybody interested in how use a cross compresor (all works exactly the same) in his projects and kudos for explain the safety offset, not everybody know that feature ;)
Fantastic stuff Nich!
I'm going to find that very handy indeed.
Thanks!
Quote from: Nich on 21:15, 11 October 11
I also want to provide a version of the decompression routines that actually work with WinAPE without having to make significant corrections to it.
There's actually only a couple of minor changes:
1. Remove the : from the comment line at the top or add an extra ;
2. Remove one t from the gett4bits label
3. Replace the [] with () for all the [iy+d] instructions
Maybe these changes should be recommended to the original author, and maybe WinAPE should support square brackets for indexed addressing even though it's not MAXAM compatible.
Nice work Nich.
The decompressor on the CPCRulez website (http://cpcrulez.fr/applications_tools_cruncher_exomiser2_Z80.htm) assembles with Maxam/WinAPE out of the box.
I think you just need to Remark one of the comments at the bottom.
Quote from: SyX on 18:19, 11 October 11
And if you need help to adding at one of your projects only tell me ;)
Actually I take that offer for our Giana Sister Clone :-) I intend to continue this project now, had no time to work at it since February. I come back to crunching as soon as needed :-)))
Quote from: Executioner on 00:31, 12 October 11
There's actually only a couple of minor changes:
1. Remove the : from the comment line at the top or add an extra ;
2. Remove one t from the gett4bits label
3. Replace the [] with () for all the [iy+d] instructions
Maybe these changes should be recommended to the original author, and maybe WinAPE should support square brackets for indexed addressing even though it's not MAXAM compatible.
Is it possible for you to fix the bug that prevents colons from being included within comments?
Just double colon ;; at the start of the comment.
Quote from: Nich on 19:08, 12 October 11
Is it possible for you to fix the bug that prevents colons from being included within comments?
If it were a bug, I'd fix it, but Maxam does the same. I'm thinking maybe I could set up some default options where this (and eg. operator precedence) could be changed just by adding assembler options.
The Executioner is right.
This is not a bug, it's a feature! It allows to add code after comments in the same line. And it's good to have it that way.
Quote from: TFM/FS on 18:19, 14 October 11
This is not a bug, it's a feature! It allows to add code after comments in the same line. And it's good to have it that way.
??? Why would you want to do that? Every programming example I've seen puts comments after the code if the comment is on the same line.
Anyway, if the 'bug' is a feature of
Maxam, then I accept Executioner's decision not to fix this problem.
Quote from: Nich on 19:25, 16 October 11
??? Why would you want to do that? Every programming example I've seen puts comments after the code if the comment is on the same line.
I agree it's a bit silly, and I'd like to fix it, but that may break a lot of existing code. Maybe instead of a load of options in the files allowing you to change the way WinAPE assembler works there could be one check box, "Strict Maxam Compatibility" which enabled code after comments, and disabled such things as macros. Problem is you'd need to turn it on/off for different files, so it may be better to put something like ;;$M at the top of any file you want strict compatibility in.
Quote from: Nich on 19:25, 16 October 11
??? Why would you want to do that? Every programming example I've seen puts comments after the code if the comment is on the same line.
Haha, have you ever seen Odiesofts Code? Every line is nearly full (250 chars?). Opcodes, Comments, Opcodes ... Why? Because memory is limited, and the READ instruction is limited. We're talking about a CPC, not emulation.
So my code it nice at the beginning, but with adding more functions sometimes every character has to be saved to be pressed in a single file.
However, that's the way we did it in the old days (and I like still to work that way, without PCs!). Today everybody first buys a PC to be able to program for the CPC. Today you don't care about RAM and filesize, but in the old days it was different. And THEREFORE Arnor was smart enought to introduce that FEATURE :laugh:
Quote from: Executioner on 23:46, 17 October 11
I agree it's a bit silly, and I'd like to fix it, but that may break a lot of existing code. Maybe instead of a load of options in the files allowing you to change the way WinAPE assembler works there could be one check box, "Strict Maxam Compatibility" which enabled code after comments, and disabled such things as macros. Problem is you'd need to turn it on/off for different files, so it may be better to put something like ;;$M at the top of any file you want strict compatibility in.
This is now very IMHO.... It I have to assemble code then I have no time to waste. So I can use WinApe and if it works then it's great! But it there are problems, then I will just take another assembler - for me this is MAXAM on ROM. And if I use that under Winape then it runs very quick. But I will not waste time to search the problem of incompatibiltity. Maybe other people think the same way. So what ever you do, IMHO it would be great to keep it easy :) :) :)
Hi all!
I've just seen the CPCWiki article only uses the official exomizer release, and therefore you don't get my optimizations. Anyway, the depackers have been recently optimized by Antonio Villena, and I'm gonna start a thread about it.
Quote from: Executioner on 00:31, 12 October 11
2. Remove one t from the gett4bits label
3. Replace the [] with () for all the [iy+d] instructions
Ops :-[ , I don't know how those got there in the official exomizer release, I guess I didn't check it too much because it happened like ten months after I had released my depackers. The new versions I just sent to Magnus Lind shouldn't have those bugs.
Quote from: SyX on 18:26, 10 October 11Apropos of compressor (the Babel subject is other world, jejejeje, and wait to add the dialects to the discussion ;) ), i don't trust in exomizer, i have used in a few projects without problems even in backward mode, but i have crunched a few files that the z80 decruncher can not decrunch and passed a lot of time debugging my code :-[
Do you still have those files?
Quote from: SyX on 18:26, 10 October 11i have converted packfire (http://www.pouet.net/prod.php?which=54840) tiny mode to z80, and how aplib, it doesn't need a buffer in ram how exomizer (the table is in the first 26 bytes of every crunched file) and the decrunched files are the same size that exomizer (or even a few bytes smaller), but is much much more slower and the tiny mode only can compress up 32 KBs, not a single byte more.
When I first converted exomizer depackers to Z80, I noticed the format was wasting 2 bits, so I made an optimizer to cut those 2 bits and also resort the bit stream to be read from left to right (faster on Z80 thanks to ADD instructions). Checking Packfire's tiny mode, I noticed it's basically the same as exomizer but cutting one of those redundant bits from the "official exomizer 2 format", but not the other one, so it only has a 12,5% of probability to improve the resulting size in one byte, not a 25% like my optimizator has :P .
The fact that your depacker needs no table is interesting, but I'm not sure if the extra time it takes to get the info from the minitable is really worth it.
Quote from: Metalbrain on 19:35, 17 January 12Do you still have those files?
I think no, it happened mainly when i was making the tapes for the Mojon Twins games (a problem with a sequence of opcodes generated by z88dk!?!?!?!?), but i will give a test to your new version and if i get another "decrunching bug" i will send you :)
Quote from: Metalbrain on 19:35, 17 January 12The fact that your depacker needs no table is interesting, but I'm not sure if the extra time it takes to get the info from the minitable is really worth it.
Yes, those are the problems, bu it was more a proof of concept and an exercise for refreshing my 68000, the "damned" decruncher abuse of 68000 registers and addressing modes, so much flexibles that our poor z80 :P , i had to use self-modify code and that is not always the best solution for so little code