File:  [gforth] / gforth / asm / numref.fs
Revision 1.4: download - view: text, annotated - select for diffs
Sat Sep 23 15:47:05 2000 UTC (23 years, 6 months ago) by anton
Branches: MAIN
CVS tags: v0-5-0, HEAD
changed FSF address in copyright messages

    1: \ refs.fs
    2: 
    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., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
   20: 
   21: 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: require ./basic.fs
   95: 
   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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>