-
Notifications
You must be signed in to change notification settings - Fork 0
/
depack.gen
126 lines (95 loc) · 3.16 KB
/
depack.gen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
;macro to get a bit from the bitstream
;carry if bit is set, nocarry if bit is clear
;must be entered with second registerset switched in!
GET_BIT_FROM_BITSTREAM: MACRO
add a,a ;shift out new bit
jp nz,GET_BIT_FROM_BITSTREAM@$YM ;if remaining value isn't zere, we're done
ld a,(hl) ;get 8 bits from bitstream
inc hl ;increase source data address
rla ;(bit 0 will be set!!!!)
GET_BIT_FROM_BITSTREAM@$YM:
ENDM
;In: HL: source
; DE: destination
depack: inc hl ;skip original file length
inc hl ;which is stored in 4 bytes
inc hl
inc hl
ld a,128
exx
ld de,1
exx
depack_loop:
GET_BIT_FROM_BITSTREAM ;get compression type bit
jp c,output_compressed ;if set, we got lz77 compression
ldi ;copy byte from compressed data to destination (literal byte)
;unrolled for extra speed
GET_BIT_FROM_BITSTREAM ;get compression type bit
jp c,output_compressed ;if set, we got lz77 compression
ldi ;copy byte from compressed data to destination (literal byte)
GET_BIT_FROM_BITSTREAM ;get compression type bit
jp c,output_compressed ;if set, we got lz77 compression
ldi ;copy byte from compressed data to destination (literal byte)
jp depack_loop
;handle compressed data
output_compressed:
ld c,(hl) ;get lowest 7 bits of offset, plus offset extension bit
inc hl ;to next byte in compressed data
output_match:
ld b,0
bit 7,c
jr z,output_match1 ;no need to get extra bits if carry not set
GET_BIT_FROM_BITSTREAM ;get offset bit 10
rl b
GET_BIT_FROM_BITSTREAM ;get offset bit 9
rl b
GET_BIT_FROM_BITSTREAM ;get offset bit 8
rl b
GET_BIT_FROM_BITSTREAM ;get offset bit 7
jp c,output_match1 ;since extension mark already makes bit 7 set
res 7,c ;only clear it if the bit should be cleared
output_match1:
inc bc
;return a gamma-encoded value
;length returned in HL
exx ;to second register set!
ld h,d
ld l,e ;initial length to 1
ld b,e ;bitcount to 1
;determine number of bits used to encode value
get_gamma_value_size:
exx
GET_BIT_FROM_BITSTREAM ;get more bits
exx
jr nc,get_gamma_value_size_end ;if bit not set, bitlength of remaining is known
inc b ;increase bitcount
jp get_gamma_value_size ;repeat...
get_gamma_value_bits:
exx
GET_BIT_FROM_BITSTREAM ;get next bit of value from bitstream
exx
adc hl,hl ;insert new bit in HL
get_gamma_value_size_end:
djnz get_gamma_value_bits ;repeat if more bits to go
get_gamma_value_end:
inc hl ;length was stored as length-2 so correct this
exx ;back to normal register set
ret c
;HL' = length
push hl ;address compressed data on stack
exx
push hl ;match length on stack
exx
ld h,d
ld l,e ;destination address in HL...
sbc hl,bc ;calculate source address
pop bc ;match length from stack
ldir ;transfer data
pop hl ;address compressed data back from stack
GET_BIT_FROM_BITSTREAM ;get compression type bit
jp c,output_compressed ;if set, we got lz77 compression
ldi ;copy byte from compressed data to destination (literal byte)
GET_BIT_FROM_BITSTREAM ;get compression type bit
jp c,output_compressed ;if set, we got lz77 compression
ldi ;copy byte from compressed data to destination (literal byte)
jp depack_loop