-
Notifications
You must be signed in to change notification settings - Fork 2
/
lzedec.mac
126 lines (113 loc) · 2.48 KB
/
lzedec.mac
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
;// LZE DECODE ROUTINE
;// Original Copyright (C)1995,2008 GORRY.
;// Porting for Z80 by Kei Moroboshi 2020/Apr
; .Z80
; PUBLIC DECODE_LZE
;==============================================================================
;LZE data decoder
;Input:
; HL LZE encoded data address(*)
; DE extracting address
;(*)lze.exe add 4 byte header as extracted size(big-endian).
;Therefore, you must set HL as LZE data top + 4(skip the header).
;Broken:
; AF,BC,DE,HL,AF',BC',DE',HL',IY
;Example:
; LD HL,LZEDATA+4
; LD DE,EXTRACT_AREA
; CALL DECODE_LZE
;==============================================================================
DECODE_LZE: ;ENTRY
LD IY,MAINLP ;[[[or remove]]]
PUSH DE
EXX
POP DE
LD BC,0 ;CopyCount=0
EXX
LD D,8
LD B,1 ;BitCount=1, first
STORE: LD A,(HL) ;*(DECODEPtr++) = *(LZEPtr++);
INC HL
EXX
LD (DE),A ;DE'=DECODEPtr
INC DE
EXX
MAINLP:
DJNZ SKIP ;BitTest() {
LD C,(HL) ;
INC HL
LD B,D ;8
SKIP: SLA C ;}
JR C,STORE ;1:Store
;0x:Copy
;Copy Byte Distance or Word Distance
DJNZ SKIP0 ;BitTest() {
LD C,(HL) ;
INC HL
LD B,D ;8
SKIP0: SLA C ;}
JR C,COPYWD ;01:Copy with Word Distance
;00:Copy with Byte Distance
COPYBD:
DJNZ SKIP00 ;BitTest() {
LD C,(HL) ;
INC HL
LD B,D ;8
SKIP00: SLA C ;}
EXX ;BC:CopyCount is already 0;
RL C ;adc CopyCount,CopyCount
EXX
DJNZ SKIP01 ;BitTest() {
LD C,(HL) ;
INC HL
LD B,D ;8
SKIP01: SLA C ;}
LD A,(HL) ;LoadDistanceB();
INC HL
EXX
LD L,A ;Distance = -256+((int)*(LZEPtr++));
LD H,0FFH
RL C ;adc CopyCount,CopyCount
;
CPCNTP2: ;CopyCount ++;
INC C ;inc CopyCount
CPCNTP1:
INC BC ;inc CopyCount
;Copy() {
ADD HL,DE ; HL':CopyPtr=HL':Distance + DE':DECODEPtr
LDIR ;} //BC':CopyCount would be 0
EXX
JP (IY) ;[[[JP/JR MAINLP]]]
;COPY with Word Distance
COPYWD:
LD A,(HL) ;LoadDistanceW() {
INC HL
EX AF,AF'
LD A,(HL)
INC HL
EXX
LD L,A ;L=DistanceL
EX AF,AF' ;A=DistanceH
;mov CopyCount,Distance
RRA ;shr Distance,1
RR L
RRA ;shr Distance,1
RR L
RRA ;shr Distance,1
RR L
OR 0E0H ;or DistanceH,0e0h
LD H,A ;HL=(Distance>>3) | 0xE000;
EX AF,AF' ;if ( (CopyCount &= 7) != 0 ) {
AND 7 ; CopyCount += 2; Copy();
LD C,A
JP NZ,CPCNTP2 ;[[[ or JR ]]]
EXX ;}else { // if CopyCount == 0
LD A,(HL) ; LoadCopyCount() {
INC HL
EXX
LD C,A ; } C'=CopyCountL
OR A ;if ( CopyCount==0 ) goto DECODE_END
JP NZ,CPCNTP1 ;[[[ or JR ]]]
;else goto CPCNTP1
DECODE_END:
RET