[gforth] / gforth / asm / numref.fs  

gforth: gforth/asm/numref.fs


1 : crook 1.5 \ numref.fs
2 : pazsan 1.1
3 : anton 1.6 \ Copyright (C) 1998,2001 Free Software Foundation, Inc.
4 : anton 1.3
5 :     \ This file is part of Gforth.
6 :    
7 :     \ Gforth is free software; you can redistribute it and/or
8 :     \ modify it under the terms of the GNU General Public License
9 :     \ as published by the Free Software Foundation; either version 2
10 :     \ of the License, or (at your option) any later version.
11 :    
12 :     \ This program is distributed in the hope that it will be useful,
13 :     \ but WITHOUT ANY WARRANTY; without even the implied warranty of
14 :     \ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 :     \ GNU General Public License for more details.
16 :    
17 :     \ You should have received a copy of the GNU General Public License
18 :     \ along with this program; if not, write to the Free Software
19 : anton 1.4 \ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
20 : anton 1.3
21 : pazsan 1.1 0 [IF]
22 :    
23 :     This is a generic solution for doing labels (forward and backward
24 :     references) in an assembler program.
25 :    
26 : crook 1.5 How to use local labels
27 :     =======================
28 : pazsan 1.1
29 :     Example:
30 :    
31 :     Label 10pause
32 :     10 # ldy,
33 :     1 $: dey,
34 :     1 $ bne,
35 :     rts,
36 :     End-Label
37 :    
38 :     "n $:" defines an address reference. "n $" returns the address of the
39 :     reference defined with "n $:".
40 :    
41 :    
42 : crook 1.5 How to embed local labels in your assembler
43 :     ===========================================
44 :    
45 :     At the moment all references are forward references, meaning all
46 :     references are resolved at the end of the definition.
47 : pazsan 1.1
48 :     The Simple Resolver
49 : crook 1.5 -------------------
50 : pazsan 1.1
51 : crook 1.5 The only special thing is how a label is resolved. Numref does this by
52 :     executing a resolver-word. For example, consider a two byte opcode
53 :     with the second byte as branch-offset. The resolver-word would look
54 :     like this:
55 : pazsan 1.1
56 : crook 1.5 : doresolve ( iaddr -- )
57 : pazsan 1.1 dup ref-addr @ - swap 1+ X c! ;
58 :    
59 :     iaddr is the address of the instruction with the reference that must
60 :     be resolved. The destination address of the reference is stored at ref-addr.
61 :    
62 : crook 1.5 The resolver-word must be registered like this:
63 :    
64 :     "' doresolve TO std-resolver"
65 :    
66 :     This is not a deferred word!
67 : pazsan 1.1
68 :     Complex Resolving
69 : crook 1.5 -----------------
70 : pazsan 1.1
71 : crook 1.5 To support different cpu-instruction with different operand formats it
72 :     is possible to find out the type of opcode by accessing the target's
73 :     memory in doresolve. This works for very simple processors, e.g. for
74 :     6502 it is very easy to find out whether we have a 2-byte absolute
75 :     address or a 1-byte relative address.
76 : pazsan 1.1
77 : crook 1.5 If this method is too difficult, it is possible to store additional
78 : pazsan 1.1 information in the resolve structure.
79 :    
80 :     When assembling an opcode you should find out whether the address is a
81 : crook 1.5 reference and then store the xt of a special resolver word in the
82 :     resolve structure by "ref-resolver !", or store some additional data
83 :     in the resolve structure by "ref-data !", if one data field is not
84 :     enough, allocate memory and use ref-data as pointer to it.
85 : pazsan 1.1
86 : crook 1.5 Internal structure
87 :     ==================
88 : pazsan 1.1
89 : crook 1.5 There is a heap buffer to store the references. The structure of one
90 :     entry is:
91 : pazsan 1.1
92 :     1 cell ref-link
93 :     1 cell ref-flag \ mixture of tag-number
94 :     \ and tag type
95 :     1 cell ref-resolver \ xt of resolver
96 :     1 cell ref-addr \ pointer to destination or on reference
97 :     \ instruction
98 :     \ (start of the instruction)
99 :     1 cell ref-data \ additional information for resolver
100 :    
101 :     [THEN]
102 :    
103 : pazsan 1.2 require ./basic.fs
104 : pazsan 1.1
105 :     also assembler definitions
106 :    
107 :     hex
108 :    
109 :     0 value ref-marker \ tells us that address is an reference
110 :    
111 :     0 value ref-now \ points to the reference we are working on
112 :    
113 :     : ref-link ref-now ;
114 :     : ref-flag ref-now cell+ ;
115 :     : ref-resolver ref-now 2 cells + ;
116 :     : ref-adr ref-now 3 cells + ;
117 :     : ref-addr ref-now 3 cells + ;
118 :     : ref-data ref-now 4 cells + ;
119 :     : ref-tag-len 5 cells ;
120 :    
121 :     : ref-resolve ref-resolver @ execute ;
122 :    
123 :     : ref? ( -- )
124 :     ref-marker
125 :     false TO ref-marker ;
126 :    
127 :     : forward? ( target-addr -- target-addr false | true )
128 :     dup there = ref? and dup
129 :     IF nip THEN ;
130 :    
131 :     :noname false TO ref-marker ; propper8 chained
132 :    
133 :     variable ref-heap 0 ref-heap !
134 :    
135 :     ' drop value std-resolver
136 :    
137 :     : ref! ( flags/nr -- )
138 :     \G stores a reference tag
139 :     \ get mem for tag
140 :     ref-tag-len allocate throw to ref-now
141 :     \ build link
142 :     ref-heap @ ref-link ! ref-link ref-heap !
143 :     there ref-adr !
144 :     std-resolver ref-resolver !
145 :     ref-flag ! ;
146 :    
147 :     : $ ( num -- address )
148 :     \G makes a reference source with the next instruction
149 :     01ff and 0200 or ref! there ;
150 :    
151 :     : $: ( num -- )
152 :     \G makes a reference target
153 :     01ff and 0a00 or ref! ;
154 :    
155 :     : g$: ( num -- )
156 :     \G makes a reference target for a global label
157 :     01ff and 0e00 or ref! ;
158 :    
159 :     : g$ ( num -- addr )
160 :     \G searches a global label and gets its address
161 :     01ff and 0e00 or
162 :     ref-heap BEGIN dup >r @ dup WHILE 2dup cell+ @ =
163 :     IF nip to ref-now
164 :     ref-link @ r> !
165 :     ref-adr @
166 :     ref-now free throw EXIT THEN
167 :     r> drop
168 :     REPEAT 2drop -1 ABORT" could not resolve G label!" ;
169 :    
170 :     : kill$: ( -- )
171 :     \G deallocs the complete reference heap
172 :     ref-heap @ BEGIN dup WHILE dup @ swap free throw REPEAT drop
173 :     0 ref-heap ! ;
174 :    
175 :     : find$: ( adr nr -- )
176 :     0800 or
177 :     ref-heap
178 :     BEGIN dup >r @ dup WHILE 2dup cell+ @ =
179 :     IF nip to ref-now
180 :     r> drop
181 :     ref-resolve EXIT
182 :     THEN
183 :     r> drop
184 :     REPEAT 2drop -1 ABORT" could not resolve label!" ;
185 :    
186 :     : solve$
187 :     ref-heap dup >r @
188 :     BEGIN dup WHILE dup cell+ @ 0E00 and 0200 =
189 :     IF to ref-now
190 :     ref-link @ r@ !
191 :     ref-now >r
192 :     ref-adr @ ref-flag @ ( 01ff and ) find$:
193 :     r> to ref-now
194 :     ref-link ( dup >r ) @
195 :     ref-now free throw
196 :     ELSE
197 :     r> drop
198 :     dup >r @
199 :     THEN
200 :     REPEAT r> drop drop kill$: ;
201 :    
202 :     ' solve$ end-code8 chained
203 :    
204 :     previous definitions

CVS Admin

Powered by ViewCVS 1.0-dev
(Powered by ViewCVS)

ViewCVS and CVS Help