• R/O
  • SSH
  • HTTPS

oricsdk:


File Info

Rev. 1154
Size 4,090 bytes
Time 2014-08-11 03:19:54
Author dbug
Log Message

(empty log message)

Content



; Packed source data adress
#define	ptr_source			tmp0	

; Destination adress where we depack
#define	ptr_destination		tmp1	

; Point on the end of the depacked stuff
#define	ptr_destination_end	tmp2	

; Temporary used to hold a pointer on depacked stuff
#define ptr_source_back		tmp3	

; Temporary
#define offset				tmp4	

#define mask_value			reg0
#define nb_src				reg1
#define nb_dst				reg2


UnpackError
	rts

UnpackLetters	.byt "LZ77"


; void file_unpack(void *ptr_dst,void *ptr_src)

_file_unpack
.(
	ldy #0
	lda (sp),y
	sta ptr_destination
	iny
	lda (sp),y
	sta ptr_destination+1


	; Source adress
	ldy #2
	lda (sp),y
	sta ptr_source
	iny
	lda (sp),y
	sta ptr_source+1


	; Test if it's LZ77
	ldy #3
	.(
test_lz77
	lda (ptr_source),y
	cmp UnpackLetters,y
	bne UnpackError
	dey 
	bpl test_lz77
	.)


	; Get the unpacked size, and add it to the destination
	; adress in order to get the end adress.
	ldy #4
	clc
	lda ptr_destination
	adc (ptr_source),y
	sta ptr_destination_end+0
	iny
	lda ptr_destination+1
	adc (ptr_source),y
	sta ptr_destination_end+1


	; Move the source pointer ahead to point on packed data (+0)
	clc
	lda ptr_source
	adc #8
	sta ptr_source
	lda ptr_source+1
	adc #0
	sta ptr_source+1


	; Initialise variables
	; We try to keep "y" null during all the code,
	; so the block copy routine has to be sure that
	; y is null on exit
	ldy #0
	lda #1
	sta mask_value
	 
unpack_loop
	; Handle bit mask
	lsr mask_value
	bne end_reload_mask

	; Read from source stream
	lda (ptr_source),y 		

	.(
	; Move stream pointer (one byte)
	inc ptr_source  		
	bne skip
	inc ptr_source+1
skip
	.)
	ror 
	sta mask_value   
end_reload_mask
	bcc back_copy

write_byte
	; Copy one byte from the source stream
	lda (ptr_source),y
	sta (ptr_destination),y

	.(
	; Move stream pointer (one byte)
	inc ptr_source
	bne skip
	inc ptr_source+1
skip
	.)

	lda #1
	sta nb_dst



_UnpackEndLoop
	;// We increase the current destination pointer,
	;// by a given value, white checking if we reach
	;// the end of the buffer.
	clc
	lda ptr_destination
	adc nb_dst
	sta ptr_destination

	.(
	bcc skip
	inc ptr_destination+1
skip
	.)
	cmp ptr_destination_end
	lda ptr_destination+1
	sbc ptr_destination_end+1
	bcc unpack_loop  
	rts
	

back_copy
	;BreakPoint jmp BreakPoint	
	; Copy a number of bytes from the already unpacked stream
	; Here we know that y is null. So no need for clearing it.
	; Just be sure it's still null at the end.
	; At this point, the source pointer points to a two byte
	; value that actually contains a 4 bits counter, and a 
	; 12 bit offset to point back into the depacked stream.
	; The counter is in the 4 high order bits.
	;clc  <== No need, since we access this routie from a BCC
	lda (ptr_source),y
	adc #1
	sta offset
	iny
	lda (ptr_source),y
	tax
	and #$0f
	adc #0
	sta offset+1

	txa
	lsr
	lsr
	lsr
	lsr
	clc
	adc #3
	sta nb_dst

	sec
	lda ptr_destination
	sbc offset
	sta ptr_source_back
	lda ptr_destination+1
	sbc offset+1
	sta ptr_source_back+1

	; Beware, in that loop, the direction is important
	; since RLE like depacking is done by recopying the
	; very same byte just copied... Do not make it a 
	; reverse loop to achieve some speed gain...
	; Y was equal to 1 after the offset computation,
	; a simple decrement is ok to make it null again.
	dey
	.(
copy_loop
	lda (ptr_source_back),y	; Read from already unpacked stream
	sta (ptr_destination),y	; Write to destination buffer
	iny
	cpy nb_dst
	bne copy_loop
	.)
	ldy #0

	;// C=1 here
	lda ptr_source
	adc #1
	sta ptr_source
	bcc _UnpackEndLoop
	inc ptr_source+1
	bne _UnpackEndLoop
	rts
.)


; Taille actuelle du code 279 octets
; 0x08d7 - 0x07e8 => 239 octets
; 0x08c8 - 0x07e5 => 227 octets
; 0x08d5 - 0x0800 => 213 octets
; 0x08c9 - 0x0800 => 201 octets
; 0x08c5 - 0x0800 => 197 octets
; 0x08c3 - 0x0800 => 195 octets
; 0x08c0 - 0x0800 => 192 octets
; => 146 octets
Show on old repository browser