[gforth] / gforth / asm / numref.fs  

gforth: gforth/asm/numref.fs


1 : pazsan 1.1 \ refs.fs
2 :    
3 : anton 1.3 \ Copyright (C) 1998 Free Software Foundation, Inc.
4 :    
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 :     \ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 :    
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 :     - Who to use local labels:
27 :    
28 :     Example:
29 :    
30 :     Label 10pause
31 :     10 # ldy,
32 :     1 $: dey,
33 :     1 $ bne,
34 :     rts,
35 :     End-Label
36 :    
37 :     "n $:" defines an address reference. "n $" returns the address of the
38 :     reference defined with "n $:".
39 :    
40 :     - How to embed local labels in your assembler:
41 :    
42 :     At the moment all references are forward references, meaning,
43 :     all references are resolved at the end of the definition.
44 :    
45 :     The Simple Resolver
46 :    
47 :     The only special thing is how a label is resolved. Numref executes
48 :     therefor a resolver-word, example for a two byte opcode with the second
49 :     byte as branch-offset:
50 :    
51 :     : doresovle ( iaddr -- )
52 :     dup ref-addr @ - swap 1+ X c! ;
53 :    
54 :     iaddr is the address of the instruction with the reference that must
55 :     be resolved. The destination address of the reference is stored at ref-addr.
56 :    
57 :     The resolver must be registered bye "' doresolve TO std-resolve". This is
58 :     not a defered word!
59 :    
60 :     Complex Resolving
61 :    
62 :     To support different cpu-instruction with different operand formats it is
63 :     possible to find out the type of opcode bye accessing the targets' memory
64 :     in doresolve. This works for very simple processors, e.g. for 6502 it is
65 :     very easy to find out whether we have a 2-byte absolute address or a 1-byte
66 :     relative address.
67 :    
68 :     If this method is to difficult, it is possible to store additional
69 :     information in the resolve structure.
70 :    
71 :     When assembling an opcode you should find out whether the address is a
72 :     reference and then store the xt of a special
73 :     resolver word in the resolve structure by "ref-resolver !", or store some
74 :     additional data in the resolve structure by "ref-data !", if one data field
75 :     is not enough allocate memory and use ref-data as pointer to it.
76 :    
77 :     - Internal strucutre:
78 :    
79 :     There is a heap buffer to store the references.
80 :     The structure of one entry is:
81 :    
82 :     1 cell ref-link
83 :     1 cell ref-flag \ mixture of tag-number
84 :     \ and tag type
85 :     1 cell ref-resolver \ xt of resolver
86 :     1 cell ref-addr \ pointer to destination or on reference
87 :     \ instruction
88 :     \ (start of the instruction)
89 :     1 cell ref-data \ additional information for resolver
90 :    
91 :    
92 :     [THEN]
93 :    
94 : pazsan 1.2 require ./basic.fs
95 : pazsan 1.1
96 :     also assembler definitions
97 :    
98 :     hex
99 :    
100 :     0 value ref-marker \ tells us that address is an reference
101 :    
102 :     0 value ref-now \ points to the reference we are working on
103 :    
104 :     : ref-link ref-now ;
105 :     : ref-flag ref-now cell+ ;
106 :     : ref-resolver ref-now 2 cells + ;
107 :     : ref-adr ref-now 3 cells + ;
108 :     : ref-addr ref-now 3 cells + ;
109 :     : ref-data ref-now 4 cells + ;
110 :     : ref-tag-len 5 cells ;
111 :    
112 :     : ref-resolve ref-resolver @ execute ;
113 :    
114 :     : ref? ( -- )
115 :     ref-marker
116 :     false TO ref-marker ;
117 :    
118 :     : forward? ( target-addr -- target-addr false | true )
119 :     dup there = ref? and dup
120 :     IF nip THEN ;
121 :    
122 :     :noname false TO ref-marker ; propper8 chained
123 :    
124 :     variable ref-heap 0 ref-heap !
125 :    
126 :     ' drop value std-resolver
127 :    
128 :     : ref! ( flags/nr -- )
129 :     \G stores a reference tag
130 :     \ get mem for tag
131 :     ref-tag-len allocate throw to ref-now
132 :     \ build link
133 :     ref-heap @ ref-link ! ref-link ref-heap !
134 :     there ref-adr !
135 :     std-resolver ref-resolver !
136 :     ref-flag ! ;
137 :    
138 :     : $ ( num -- address )
139 :     \G makes a reference source with the next instruction
140 :     01ff and 0200 or ref! there ;
141 :    
142 :     : $: ( num -- )
143 :     \G makes a reference target
144 :     01ff and 0a00 or ref! ;
145 :    
146 :     : g$: ( num -- )
147 :     \G makes a reference target for a global label
148 :     01ff and 0e00 or ref! ;
149 :    
150 :     : g$ ( num -- addr )
151 :     \G searches a global label and gets its address
152 :     01ff and 0e00 or
153 :     ref-heap BEGIN dup >r @ dup WHILE 2dup cell+ @ =
154 :     IF nip to ref-now
155 :     ref-link @ r> !
156 :     ref-adr @
157 :     ref-now free throw EXIT THEN
158 :     r> drop
159 :     REPEAT 2drop -1 ABORT" could not resolve G label!" ;
160 :    
161 :     : kill$: ( -- )
162 :     \G deallocs the complete reference heap
163 :     ref-heap @ BEGIN dup WHILE dup @ swap free throw REPEAT drop
164 :     0 ref-heap ! ;
165 :    
166 :     : find$: ( adr nr -- )
167 :     0800 or
168 :     ref-heap
169 :     BEGIN dup >r @ dup WHILE 2dup cell+ @ =
170 :     IF nip to ref-now
171 :     r> drop
172 :     ref-resolve EXIT
173 :     THEN
174 :     r> drop
175 :     REPEAT 2drop -1 ABORT" could not resolve label!" ;
176 :    
177 :     : solve$
178 :     ref-heap dup >r @
179 :     BEGIN dup WHILE dup cell+ @ 0E00 and 0200 =
180 :     IF to ref-now
181 :     ref-link @ r@ !
182 :     ref-now >r
183 :     ref-adr @ ref-flag @ ( 01ff and ) find$:
184 :     r> to ref-now
185 :     ref-link ( dup >r ) @
186 :     ref-now free throw
187 :     ELSE
188 :     r> drop
189 :     dup >r @
190 :     THEN
191 :     REPEAT r> drop drop kill$: ;
192 :    
193 :     ' solve$ end-code8 chained
194 :    
195 :     previous definitions

CVS Admin

Powered by ViewCVS 1.0-dev
(Powered by ViewCVS)

ViewCVS and CVS Help