

	StoneCracker v4.01 - Command and Data File Cruncher



	Written and developed by Jouni 'Mr.Spiv' Korhonen. I am 20 years old
	_poor_ student from cold Finland. I study mathematics (and computer
	science) in Helsinki University and every now and then waste a bit
	of my spare time programming programs like StoneCracker.

	This program is PD, freeware or what ever you want to call it and it
	may be copied and used freely. But StoneCracker is NOT allowed to be
	sold or used for any commercial purposes without my permission.

	To contact me write to:		PL 176
					11101 Riihimaki
					Finland

	This will just be a brief overview of this cruncher utility. If you
	can use such programs like PowerPacker or Imploder you can also use
	the fabulous StoneCracker too.



	First I will write down all the things StoneCracker v4.01 can do...

	· There are three different filetypes that can be crunched with
	StoneCracker: command files (=normal executable files), pure data
	and absolute memory address located files.

	· Command file cruncher can support standard hunk structures with
	hunk_code, hunk_data, hunk_bss and hunk_reloc32. Hunk_debug and
	hunk_symbol are removed when found. Note that StoneCracker refuses
	to crunch programs which can not be relocated correctly after
	decrunching process e.g programs with strange hunk structure, not
	supported hunk type or overlayed files.

	· Data files are crunched and saved as raw data. Only the decruncher
	infoheader is added to the saved file. The form of the infoheader is:
	DC.B "S401"	;the file was crunched with S401 algorithm
	DC.L $000000	;original file length
	DC.L $000000	;crunched file length
	There is a sourcecode for the data decruncher at the end of this file.

	· Absolute memory address located files are crunched as raw data so
	you can not relocate any command files to absolute memory addresses.
	Before saving the crunched file you are asked for some information
	for the decruncher:
	Load address - Locate your decrunched program here
	High address - End of the memory area the decruncher may change or
		       corrupt while decrunching
	Jump address - After decrunching jump here (start your program)
	Decruncher   - Place the decruncher code here (needs 230 bytes)
	DmaCon       - Set or mask the dmacon ($dff096) bits before
		       decrunching ($0 for no action)
	IntEna       - Set or mask the interrupt enable ($dff09a) bits
		       before decrunching ($0 for no action)
	System Stack - Relocate SSP (supervisor or exception stackpointer).
		       When this field is non zero (<>$0) the value is moved
		       to SSP and processor turned to SuperVisor mode (I use
		       illegal instruction vector (at $0010.w) and command
		       Illegal). You better turn interrupts off when you
		       relocate the SSP.
	Accept       - Accept all values and save the file with a decruncher.
	Notice that stacks are not used during decrunch process. If you change
	dmacon or intena remember that decruncher does not restore original
	values. Be careful with this filetype.

	· BE CAREFUL WITH ODD VALUES! Decrunchers do not like odd values! It
	is not a problem with data decruncher since you can take care of the
	code yourself. But absolute address decruncher will crash!

	· StoneCracker checks automatically if the file you want to crunch, is
	already crunched with StoneCracker. All the three file types can be
	decrunched and saved in their original form.

	· When there is a crunched or decrunched file in buffer and you have
	not saved the file yet, you can see a '*'-character as a sign of that
	in the menubar. After saving the file the sign will disappear. When
	quiting or going to sleep StoneCracker shows a requester if there is
	a file in buffer which is not saved yet.

	· Crunched data or absolute files can also be saved to tracks. Nice
	option for programs that use trackdisk. Data files are tracked in the
	same format as a normal data file. Absolute files are tracked with the
	decruncher header but not with the hunk stuff in front of a normal
	absolute file (tracked file is 36 bytes shorter).

	· Delete files is useful when you need to kill some diskspace
	consuming files from your disks.

	· Sleep - This will free all allocated buffers, close windows, screens
	and generally everything that StoneCracker needs. Only a little sleep
	window appears to your WorkBench screen. You can run StoneCracker
	again by pressing the right mousebutton on an activated sleep window.

	· File type - Select which type files you want to crunch. Note that if
	you change file type before saving the crunched file it will not
	affect the file which is already in buffer waiting for saving. Default
	is set to command file type.

	· Decrunch color - Which color will flash ('Let there be light!')
	during decrunch process. Default is set to no flashing.

	· Show buffer info gives you some statistics about the buffer's
	contents. Whether it is empty or is the file in the buffer crunched
	or decrunched and which file type.

	· Then there are several settings for hunklab. Note that they affect
	only to command files when files are loaded into the buffer.
	Remove Hunk_symbol - Loaded command file is scanned and if any
			     Hunk_symbols are found they are removed from the
			     file. Default setting is remove all Hunk_symbols.
	Remove Hunk_debug  - Same things to Hunk_debug as above. Note that the
			     decruncher can not relocate programs that have
			     Hunk_debugs or Hunk_symbols.
	Hunk_code to Chip  - Force all found Hunk_codes to be loaded into Chip
			     memory.
	Hunk_data to Chip  - Same as above for all Hunk_datas.
	Hunk_bss to Chip   - Same as above for all Hunk_bsses.

	Well, I started developing this cruncher utility in November -91. I
	was inspirated by the article of LZRW1 algorithm developed by the
	dynamic duo ZIV-Lempel. Because this algorithm was really _fast_ I
	made some testing with it. I was disappointed of the poor efficiency
	and rewrote the algorithm using other methods to save crunched data.
	The efficieny got heaps better but at the same time I lost most of
	the speed. So the only thing what is left from the original algorithm
	is the search funtion, everything else is developed and written by me.
	A pity the algorithm still has poor efficiency but the crunching time
	is _short_ - for example DPaint IV takes only 20 seconds! In average
	StoneCracker is about _18_ (yes!) times _faster_ than PowerPacker.

	A demoversion of StoneCracker (v4.00) got spread around and later I
	thought it was a misstake. I should not have allowed it to happen and
	consentrate more on v4.01. You know v4.00 was very plain. But now on
	it is quite sure that I will not develope StoneCracker very much. Bug
	fixes will be released when needed, maybe a better hunklab and turbo
	mode (based almost directly on LZRW1). Anyway now I have finished my
	research with crunching algorithms and reached what I wanted to - to
	program a _fast_ and useful cruncher for my own purposes. I have
	noticed that the only thing to develope (only worth developing) is
	the user interface and it has nothing to do with algorithms so...
	Now it is time to find a new district to explore! But let us continue
	with the documentation...

	Decrunchers are a combination of fast and short code. Especially the
	command file decruncher was developed carefully and there should not
	be much to optimize anymore (erm... I could rip four bytes away). The
	decruncher and relocator take only 316 bytes (ha, beat it!). Then
	there are also 104 bytes long control program which calls decruncher
	and afterwards frees extra memory needed by the decruncher. After
	decrunching only the original and control programs will be left.

	The whole cruncher utility was written from scratch in assembly and
	that is probably the reason why the program is so short (about 20Kb).
	Very big thanks must go to * NICO FRANÇOIS * for the REQTOOLS which I
	used for all requesters.

	StoneCracker was developed using a normal A2000c (1.3) with standard
	equipment (HD, extra memory etc). The program is KickStart 2.04
	compatible and works as well in A3000. Because the program is
	written in assembly and my second serious attempt in 'clean' system
	programming it is quite obvious that there are some bugs around.
	Please let me know about all the bugs so I can fix them. Please
	contact me via the address at the beginning of this file since it
	will be quite hard to reach me next year using other medias (all
	Finns know what I mean...).

	There is one thing that made the developement hard and slow. The lack
	of literature. I have only used Includes & Autodocs and one loose
	Abacus book as a reference. For example all my knowledge of Amiga's
	hunks and how program is loaded into memory is based on experience.
	Fortunately there are good programs around like Amiga Monitor by Timo
	Rossi. I had already finished StoneCracker v4.01 when I at last found
	a book that would have told me everything about hunks. I did not buy
	it, yet.

	I must thank following people for their help, ideas, bug-reports and
	betatesting StoneCracker: Mape alias Darxon, Hot and especially Exterm
	who found a nasty bug from the command file decruncher and drawind the
	StoneCracker logo. If Mape does	not stop nagging about utilities which
	should support _stoned_ files, I will probably have to write some
	PPmore style utilities. Next coming bigger 'Stone' utility should be
	StoneSmasher - an ultimate Hunk_Tool for editing, verifying, fixing,
	relocating, deleting and adding hunks to/from command files.

	I hope you find this program worth using although it is not the most
	fancy and powerful cruncher around. Use Imploder... It is surely the
	best! Sorry for my bad Engleesh.

	Click...


	MOVEQ #0,D0
	RTS			;succesful exit




	Now I will explain how the crunched data must be decrunched... Notice
	that S401 - algorithm does not decrunch data as almost every other
	algorithm around. The crunched data is read from low memory to high
	memory and then the decrunched data is written from low memory to high
	memory too. Like this...

	D=decrunched data, C=crunched data, M=memory area, S=security area


							+---- high memory
							|
	+---- low memory				| +---- security area
	|						| |
	MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMSSSSSSSS
	DDDDDDDDDDDDDDDDD...
	| |							
	| +------< move decrunched data <-------CCCCCCCCCCCCCCCCC
	|					|
	|					+---- start of crunched data
	+---- start of decrunched data


;-------------------------------------------------*
;- StoneCracker - v4.01 - Data decruncher
;-------------------------------------------------*
;
;inputs: a0=destination address
;	 a2=crunched data
;output: d0=0 if decrunched ok
;	 d0=-1 if not StoneCracker 'S401' data
;
;--------------	decrunch data - uses d0-d6/a0-a4
lzd_decrunch:	cmp.l	#"S401",(a2)+
		beq.s	lzd_trapantti_kayntiin
		moveq	#-1,d0
		rts

lzd_trapantti_kayntiin:
		moveq	#2,d5
		moveq	#15,d6

		move.l	a0,a3
		add.l	(a2)+,a3		;uncrunched length
		move.l	(a2)+,d0		;crunched length
lzd_color:	lea	$dff1fe,a4

		move	(a2)+,d0
		lsr	#1,d6
		addx	d0,d0
		bra.s	lzd_first

lzd_ympari_mennaan_yhteen_tullaan:
		add	d0,d0
lzd_first:	bne.s	lzd_no_ovl1
		move	(a2)+,d0
		 move	a2,(a4)			;'let there be light!'
		addx	d0,d0
lzd_no_ovl1:	bcs.s	lzd_xcopy

lzd_byte:	moveq	#0,d3
lzd_loop6:	moveq	#0,d2

		moveq	#2,d4
lzd_l1:		add	d0,d0
		bne.s	*+6
		move	(a2)+,d0
		addx	d0,d0
		addx	d2,d2
		dbf	d4,lzd_l1

		add	d2,d3
		cmp	d6,d2
		beq.s	lzd_loop6

lzd_arsi_ja_kopi_kavi_taalla:
		moveq	#7,d4
lzd_loop7:	add	d0,d0
		bne.s	*+6
		move	(a2)+,d0
		addx	d0,d0
		addx.b	d2,d2
		dbf	d4,lzd_loop7

		move.b	d2,(a0)+
		dbf	d3,lzd_arsi_ja_kopi_kavi_taalla

		bra.s	lzd_test

lzd_apuuva:	dc.b	1,2,3,-1

lzd_xcopy:	moveq	#0,d2
		moveq	#1,d4

lzd_l3:		add	d0,d0
		bne.s	*+6
		move	(a2)+,d0
		addx	d0,d0
		addx	d2,d2
		dbf	d4,lzd_l3

		moveq	#0,d3
		moveq	#0,d1
		move.b	lzd_apuuva(pc,d2.w),d3
		bmi.s	lzd_loop4

lzd_loop3:	add	d0,d0
		bne.s	lzd_no_ovl4
		move	(a2)+,d0
		addx	d0,d0
lzd_no_ovl4:	addx	d1,d1
		dbf	d3,lzd_loop3

lzd_loop4:	moveq	#7,d4
lzd_l4:		add	d0,d0
		bne.s	*+6
		move	(a2)+,d0
		addx	d0,d0
		addx	d1,d1
		dbf	d4,lzd_l4

		cmp	d5,d2
		blo.s	lzd_naeman
		moveq	#0,d2
lzd_loop5:	moveq	#0,d3

		moveq	#2,d4
lzd_l5:		add	d0,d0
		bne.s	*+6
		move	(a2)+,d0
		addx	d0,d0
		addx	d3,d3
		dbf	d4,lzd_l5

		add.l	d3,d2
		cmp	d6,d3
		beq.s	lzd_loop5

lzd_naeman:	addq.l	#2,d2
		move.l	a0,a1
		sub	d1,a1
lzd_loop8:	move.b	(a1)+,(a0)+
		subq.l	#1,d2
		bpl.s	lzd_loop8

lzd_test:	cmp.l	a3,a0
		blo	lzd_ympari_mennaan_yhteen_tullaan
		moveq	#0,d0			;decrunched ok
		rts
