;/* depack0.s */

;****************************************************************************
;*
;*  Copyright (C) 2000-2001 Eli-Jean R. Leyssens, aka Pervect of Topix
;*
;*  This file is part of the CodePressor package.
;*
;*  CodePressor is free software; you can redistribute it and/or modify
;*  it under the terms of the GNU General Public License as published by
;*  the Free Software Foundation; either version 2 of the License, or
;*  (at your option) any later version.
;*
;*  CodePressor 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 General Public License for more details.
;*
;*  You should have received a copy of the GNU General Public License
;*  along with CodePressor; if not, write to the Free Software
;*  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
;*
;*  Eli-Jean R. Leyssens can be reached via email at eli@dnd.utwente.nl
;*  snail: E-J.R. Leyssens, Schivelbeinerstr. 5, 10439 Berlin, Germany
;*
;***************************************************************************/

		AREA 	|C$$code|, CODE, READONLY

r0	RN 0
r1	RN 1
r2	RN 2
r3	RN 3
r4	RN 4
r5	RN 5
r6	RN 6
r7	RN 7
r8	RN 8
r9	RN 9
r10	RN 10
r11	RN 11
r12	RN 12
r13	RN 13
link	RN 14
		EXPORT	|depack0_part0A_begin|
		EXPORT	|depack0_part0A_start|
		EXPORT	|depack0_part0A_adrdata|
		EXPORT	|depack0_part0A_end|
		EXPORT	|depack0_part0B_begin|
		EXPORT	|depack0_part0B_stop_value|
		EXPORT	|depack0_part0B_start|
		EXPORT	|depack0_part0B_adrdata|
		EXPORT	|depack0_part0B_end|

		EXPORT	|depack0_part1_begin|
		EXPORT	|depack0_part1_main_loop|
		EXPORT	|depack0_part1_call_get_nice_byte1|
		EXPORT	|depack0_part1_call_get_nice_byte2|
		EXPORT	|depack0_part1_call_get_bits|
		EXPORT	|depack0_part1_compare|
		EXPORT	|depack0_part1_end|

		EXPORT	|depack0_part2_compare1_begin|
		EXPORT	|depack0_part2_compare1_end|
		EXPORT	|depack0_part2_compare2_begin|
		EXPORT	|depack0_part2_compare2_end|
		EXPORT	|depack0_part2_compare34_begin|
		EXPORT	|depack0_part2_compare34_end|

		EXPORT	|depack0_part3_begin|
		EXPORT	|depack0_part3_jump_main_loop|
		EXPORT	|depack0_part3_jump_program|
		EXPORT	|depack0_part3_get_nice_byte|
		EXPORT	|depack0_part3_get_bits|
		EXPORT	|depack0_part3_data|
		EXPORT	|depack0_part3_end|

|depack0_part0A_begin|
; /////////////////////////////////////////////////////////////////////////
|depack0_part0A_start|
;		adr	r4, depack0_part0A_begin
|depack0_part0A_adrdata|
		adr	r8, depack0_part3_data
; /////////////////////////////////////////////////////////////////////////
|depack0_part0A_end|

|depack0_part0B_begin|
; /////////////////////////////////////////////////////////////////////////
|depack0_part0B_stop_value|
		DCD	0
|depack0_part0B_start|
;		adr	r4, depack0_part0B_begin
|depack0_part0B_adrdata|
		adr	r8, depack0_part3_data
		ldr	r6, depack0_part0B_stop_value
; /////////////////////////////////////////////////////////////////////////
|depack0_part0B_end|

|depack0_part1_begin|
; /////////////////////////////////////////////////////////////////////////
		mov	r9, #1<<27
|depack0_part1_main_loop|
|depack0_part1_call_get_nice_byte1|
		bl	|depack0_part3_get_nice_byte|
	        subs    r0, r3, #&fe
		; r3 < &fe:
		;  - r3 is mask of which nibbles to load
		;  - next nice byte is offset of word to use as reference
		;  - no uncompressed words afterwards
		; r3 = &fe:
		;  - 1 uncompressed word
		; r3 = &ff:
		;  - run of uncompressed words, next nice byte gives length
|depack0_part1_call_get_nice_byte2|
		blne	|depack0_part3_get_nice_byte|
                add     r0, r0, #&fe
                mov     r0, r0, lsl #24
		ldrlt	r10, [ r4, r3, lsl #2]
		movle	r11, #0
		movgt	r11, r3
|depack0_decompress_words_loop|
		movge	r10, #0
		movge	r0, #255<<24
		orr	r0, r0, #1<<23
|depack0_decompress_nibbles_loop|
                ; r0 high bits contain mask of which nibbles to replace
                ; r0 will become zero once word is ready for output
                ; r10 is word being assembled
                ; r11 is number of uncompressed words (every nibble stored) following this one
		movs	r0, r0, lsl #1
|depack0_part1_call_get_bits|
		blhi	|depack0_part3_get_bits|
		movne	r10, r10, ror #32-4
		bne	|depack0_decompress_nibbles_loop|
		str	r10, [ r4, #-4]!
		subs	r11, r11, #1
		bge	|depack0_decompress_words_loop|
|depack0_part1_compare|
; /////////////////////////////////////////////////////////////////////////
|depack0_part1_end|

|depack0_part2_compare1_begin|
		cmp	r4, #0
|depack0_part2_compare1_end|

|depack0_part2_compare2_begin|
		sub	r0, r4, #0
		subs	r0, r0, #0
|depack0_part2_compare2_end|

|depack0_part2_compare34_begin|
		cmp	r4, r6
|depack0_part2_compare34_end|

|depack0_part3_begin|
; /////////////////////////////////////////////////////////////////////////
|depack0_part3_jump_main_loop|
		bne	depack0_part1_main_loop
;		mov	r0, #0
		swi	"XOS_SynchroniseCodeAreas"
|depack0_part3_jump_program|
		b	depack0_part3_jump_program

; In: r7-r9 = reader state
; Out: r3 = zero-extended value
;      r5 = 0
;      r7-r9 updated
;      r10, r12 corrupt
;
; Read one bit from the input stream. If it's 1, read and return a byte, if
; it's zero, read and return a nibble.
|depack0_part3_get_nice_byte|
		mov	r12, r14
		mvn	r5, #2	; = -3
		bl	|depack0_part3_get_bits|
		mov	r5, r3, lsl #2
		mov	link, r12
                ; Fall through...

; In: r5 = num bits to read, minus 4
;     r7-r9 = reader state:
;             r7 = unread data from last time
;             r8 -> next word to read
;             r9 bits 27-31 = number of bits remaining in r7
; Out: r3 = zero-extended value
;      r5 = 0
;      r7-r9 updated
;      nibble r3 merged into r10
;      PSR = CMP r0,#0
;
; Read bits from the input stream
|depack0_part3_get_bits|
		add	r5, r5, #4
		mov	r3, #0
|depack0_get_bits_loop|
		subs	r9, r9, #1<<27
		ldreq	r7, [ r8], #4
		movs	r7, r7, lsr #1
		adc	r3, r3, r3
		subs	r5, r5, #1
		bgt	|depack0_get_bits_loop|
		eor	r10, r10, r3, lsl #28
		cmp     r0, #0
		mov	pc, r14
|depack0_part3_data|
; /////////////////////////////////////////////////////////////////////////
|depack0_part3_end|

		END
