Annotation of gforth/asm/numref.fs, revision 1.3

1.1       pazsan      1: \ refs.fs
                      2: 
1.3     ! anton       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: 
1.1       pazsan     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: 
1.2       pazsan     94: require ./basic.fs
1.1       pazsan     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>