-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdzx7b_fast_r800.asm
148 lines (132 loc) · 4.07 KB
/
dzx7b_fast_r800.asm
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
; -----------------------------------------------------------------------------
; ZX7 Backwards by Einar Saukas, Antonio Villena
; "Standard" version (156/177/184 bytes only) for R800
; -----------------------------------------------------------------------------
; Parameters:
; HL: source address (compressed data)
; DE: destination address (decompressing)
; -----------------------------------------------------------------------------
define speed 2
macro getbitm
if speed=0
add a, a ; check next bit
call z, getbit ; no more bits left?
else
add a, a ; check next bit
jp nz, .gb1 ; no more bits left?
ld a, (hl) ; load another group of 8 bits
dec hl
adc a, a
.gb1
endif
endm
macro getbiteom odd
if (odd)=1
add a,a
else
getbitm
endif
endm
macro maicoeom odd
if odd=1
mailab: ld a, (hl) ; save some cycles avoiding call getbit
dec hl
adc a, a
jr nc, copbyo
maicoo:
else
maicoe:
endif
; determine number of bits used for length (Elias gamma coding)
.maico: ld bc, 2 ; BC=$0002
.maisi: push de ; store destination on stack
ld d, b ; D= 0
getbiteom odd^0 ; getbit with macro getbitm
if speed=0
jr c, .conti
else
jp c, .conti ; jp is 2 cycles faster when jump not taken
endif
dec c
.leval: getbiteom odd^1
rl c
rl b ; insert bit on BC
getbiteom odd^0
jr nc, .leval ; repeat, final length on BC
; check escape sequence
inc c ; detect escape sequence
jr z, exitdz ; end of algorithm
; determine offset
.conti: ld e, (hl) ; load offset flag (1 bit) + offset value (7 bits)
dec hl
rl e
jr nc, .offnd ; if offset flag is set, load 4 extra bits
getbiteom odd^1 ; load 4 bits by code
rl d ; odd bits don't need end of byte checking
getbiteom odd^0
rl d
getbiteom odd^1
rl d
getbiteom odd^0
ccf
jr c, .offnd
inc d ; equivalent to adding 128 to DE
.offnd: rr e ; insert inverted fourth bit into E
ex (sp), hl ; store source, restore destination
ex de, hl ; destination from HL to DE
adc hl, de ; HL = destination + offset + 1
if speed>1
ldd
endif
lddr
pop hl ; restore source address (compressed data)
getbiteom 1
if odd=1
jr z, mailab
jr c, maicoo
jp copbyo
else
if speed=0
jr c, .maico
jr copbye
else
if speed=1
jr c, .maico
jp copbye
else
jr nc, copbye
ld c, 2
jp .maisi
endif
endif
endif
endm
dzx7:
if speed>1
ldd ; copy literal byte
scf
maicoeom 1
exitdz: pop hl ; exit path
ret
else
ld a, $80 ; set marker bit as MSB
endif
copbye: ldd ; copy literal byte
add a, a ; read next bit, faster method
jr z, mailab ; call routine only if need to load next byte
jr c, maicoo ; next bit indicates either literal or sequence
copbyo: ldd ; loop unrolling x2
add a, a
jr nc, copbye ; next bit indicates either literal or sequence
maicoeom 0
if speed>1
else
exitdz: pop hl ; exit path
if speed=0
getbit: ld a, (hl) ; load another group of 8 bits
dec hl
adc a, a
endif
ret
maicoeom 1
endif