| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
# $Id$ |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
package CPU::Z80::Assembler::Opcode; |
|
4
|
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
=head1 NAME |
|
8
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
CPU::Z80::Assembler::Opcode - Represents one assembly expression to be computed at link time |
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
=cut |
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
14
|
|
|
|
|
|
|
|
|
15
|
31
|
|
|
31
|
|
39405
|
use strict; |
|
|
31
|
|
|
|
|
71
|
|
|
|
31
|
|
|
|
|
915
|
|
|
16
|
31
|
|
|
31
|
|
165
|
use warnings; |
|
|
31
|
|
|
|
|
77
|
|
|
|
31
|
|
|
|
|
1361
|
|
|
17
|
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
our $VERSION = '2.24'; |
|
19
|
|
|
|
|
|
|
|
|
20
|
31
|
|
|
31
|
|
192
|
use Asm::Preproc::Line; |
|
|
31
|
|
|
|
|
62
|
|
|
|
31
|
|
|
|
|
239
|
|
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
sub new { |
|
23
|
22724
|
|
|
22724
|
1
|
578648
|
my($class, %args) = @_; |
|
24
|
|
|
|
|
|
|
bless [ |
|
25
|
|
|
|
|
|
|
$args{address}, # address where loaded |
|
26
|
|
|
|
|
|
|
$args{line} || Asm::Preproc::Line->new(), |
|
27
|
|
|
|
|
|
|
# line where tokens found |
|
28
|
22724
|
|
66
|
|
|
135500
|
$args{child} || [], # list of children of this node |
|
|
|
|
100
|
|
|
|
|
|
29
|
|
|
|
|
|
|
# each child is a byte value or an expression |
|
30
|
|
|
|
|
|
|
# to compute the byte(s) |
|
31
|
|
|
|
|
|
|
], $class; |
|
32
|
|
|
|
|
|
|
} |
|
33
|
80898
|
100
|
|
80898
|
1
|
178742
|
sub address { defined($_[1]) ? $_[0][0] = $_[1] : $_[0][0] } |
|
34
|
2812
|
100
|
|
2812
|
1
|
12420
|
sub line { defined($_[1]) ? $_[0][1] = $_[1] : $_[0][1] } |
|
35
|
91693
|
50
|
|
91693
|
1
|
264400
|
sub child { defined($_[1]) ? $_[0][2] = $_[1] : $_[0][2] } |
|
36
|
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
40
|
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
use CPU::Z80::Assembler::Opcode; |
|
42
|
|
|
|
|
|
|
$opcode = CPU::Z80::Assembler::Opcode->new( |
|
43
|
|
|
|
|
|
|
address => 0, |
|
44
|
|
|
|
|
|
|
line => $line, |
|
45
|
|
|
|
|
|
|
child => [byte, byte, ["type", $expr]]); |
|
46
|
|
|
|
|
|
|
$value = $opcode->evaluate; |
|
47
|
|
|
|
|
|
|
$bytes = $opcode->bytes($address, \%symbol_table); |
|
48
|
|
|
|
|
|
|
$size = $opcode->size; |
|
49
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
51
|
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
This module defines the class that represents one assembly instruction to be |
|
53
|
|
|
|
|
|
|
added to the object code. The instruction can contain references to |
|
54
|
|
|
|
|
|
|
L expressions that are computed at link time. |
|
55
|
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=head1 EXPORTS |
|
57
|
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
Nothing. |
|
59
|
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
=head1 FUNCTIONS |
|
61
|
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
=head2 new |
|
63
|
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
Creates a new object. |
|
65
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
=head2 address |
|
67
|
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
Address where this opcode is loaded, computed at link time. |
|
69
|
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
=head2 child |
|
71
|
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
The number of children is the number of bytes stored in the object code for |
|
73
|
|
|
|
|
|
|
this instruction. |
|
74
|
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
Each child is either a scalar containing the byte value to be added to the object code, |
|
76
|
|
|
|
|
|
|
or a L expression to be evaluated at link time. In case |
|
77
|
|
|
|
|
|
|
of a word expression, then a special undef value is used as a placeholder to keep |
|
78
|
|
|
|
|
|
|
the C list the correct size. |
|
79
|
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
=head2 line |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
Get/set the line - text, file name and line number where the token was read. |
|
83
|
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
=cut |
|
85
|
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
87
|
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
=head2 evaluate |
|
89
|
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
Called when opcode is referred to by a label, returns the opcode address. |
|
91
|
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
=cut |
|
93
|
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
95
|
|
|
|
|
|
|
|
|
96
|
8661
|
|
|
8661
|
1
|
14779
|
sub evaluate { my($self) = @_; |
|
97
|
8661
|
|
|
|
|
17077
|
return $self->address; |
|
98
|
|
|
|
|
|
|
} |
|
99
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
101
|
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
=head2 bytes |
|
103
|
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
$bytes = $opcode->bytes($address, \%symbol_table); |
|
105
|
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
Computes all the expressions in C and returns the bytes string |
|
107
|
|
|
|
|
|
|
with the result object code. |
|
108
|
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
=cut |
|
110
|
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
112
|
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
sub bytes { |
|
114
|
21132
|
|
|
21132
|
1
|
35534
|
my($self, $address, $symbol_table) = @_; |
|
115
|
|
|
|
|
|
|
|
|
116
|
21132
|
|
|
|
|
31104
|
my $bytes = ""; |
|
117
|
21132
|
|
|
|
|
27770
|
for my $expr (@{$self->child}) { |
|
|
21132
|
|
|
|
|
34011
|
|
|
118
|
65613
|
100
|
|
|
|
131547
|
if (! defined($expr)) { |
|
|
|
100
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
# skip undefined values - used as placeholder for the second byte of a word |
|
120
|
|
|
|
|
|
|
} |
|
121
|
|
|
|
|
|
|
elsif (ref($expr)) { |
|
122
|
11269
|
|
|
|
|
27164
|
$bytes .= $expr->bytes($address, $symbol_table); |
|
123
|
|
|
|
|
|
|
} |
|
124
|
|
|
|
|
|
|
else { |
|
125
|
51617
|
|
|
|
|
103040
|
$bytes .= pack("C", $expr & 0xFF); |
|
126
|
|
|
|
|
|
|
} |
|
127
|
|
|
|
|
|
|
} |
|
128
|
21132
|
|
|
|
|
53415
|
return $bytes; |
|
129
|
|
|
|
|
|
|
} |
|
130
|
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
132
|
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
=head2 size |
|
134
|
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
$size = $opcode->size; |
|
136
|
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
Return the number of bytes that this opcode will generate. |
|
138
|
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
=cut |
|
140
|
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
142
|
|
|
|
|
|
|
|
|
143
|
66561
|
|
|
66561
|
1
|
106003
|
sub size { my($self) = @_; |
|
144
|
66561
|
|
|
|
|
89300
|
return scalar(@{$self->child}); |
|
|
66561
|
|
|
|
|
103867
|
|
|
145
|
|
|
|
|
|
|
} |
|
146
|
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
148
|
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
=head1 BUGS and FEEDBACK |
|
150
|
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
See L. |
|
152
|
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
=head1 SEE ALSO |
|
154
|
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
L |
|
156
|
|
|
|
|
|
|
L |
|
157
|
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
=head1 AUTHORS, COPYRIGHT and LICENCE |
|
159
|
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
See L. |
|
161
|
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
=cut |
|
163
|
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
165
|
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
1; |
|
167
|
|
|
|
|
|
|
|