1     Warning, the examples with variables in this log are
     
2     all wrong. This update explains:
     
3 
     4         !!!!!!!!!!!!!!!!!!!! Update !!!!!!!!!!!!!!!!!!!!
     
5         ! In log19.txt, I realize that my variable     !
     
6         ! handling is wrong. Variables should leave    !
     
7         ! their addresses on the stack, not their      !
     
8         ! values! We need FETCH to get the value from  !
     
9         ! the address!                                 !
    
10         !!!!!!!!!!!!!!!!!!!! Update !!!!!!!!!!!!!!!!!!!!
    
11 
    12     Now I've ported the primitive memory words.
    
13     Actually, I'd already done FETCH ('@') because it was
    
14     required by INTERPRET.
    
15 
    16             !  store value at address
    
17             @  get value from address
    
18            +!  add value to value at address
    
19            -!  subtract value from value at address
    
20            C!  store byte
    
21            C@  fetch byte
    
22          C@C!  copy 1 byte  from source addr to dest addr
    
23         CMOVE  copy n bytes from source addr to dest addr
    
24 
    25     So far, it's been easy to figure out how to test new
    
26     words as I add them. But these memory primitives aren't
    
27     so obvious because how do I know where I can read/write
    
28     memory?
    
29 
    30     The VARIABLE word which creates new variables won't be
    
31     defined until the second half of JonesFORTH runs...and
    
32     that's defined in FORTH, not asm!
    
33 
    34     Thankfully, we have some existing variables which should
    
35     be helpful:
    
36 
    37         STATE   compiling (1) or executing (0)
    
38         LATEST  Points to the most recently defined word
    
39         HERE    Points to the next free byte of memory
    
40         S0      The address of the top of the parameter stack
    
41         BASE    The current base for printing and reading numbers
    
42 
    43     So, on with the testing, starting with storing and fetching
    
44     from HERE.
    
45 
    46 HERE .
    
47 134537216
    
48 5 HERE !
    
49 HERE @ .
    
50 5
    
51 HERE @ HERE @ . .
    
52 55
    
53 
    54     Now the in-place addition and subtraction.
    
55 
    56 1 HERE +! HERE @ .
    
57 6
    
58 2 HERE -! HERE @ .
    
59 4
    
60 
    61     For the byte-wise operators, I'll set the
    
62     native-sized 4 bytes to all 1s, then it'll be
    
63     clear if we're just storing/fetching the lower
    
64     byte.
    
65 
    66 0 INVERT HERE ! HERE @ .
    
67 65535
    
68 0 HERE C! HERE @ .
    
69 65280
    
70 HERE C@ .
    
71 0
    
72 
    73     Now to copy a byte from memory to another
    
74     memory location, let's get an interesting
    
75     byte - the 'L' from 'LATEST' in the name
    
76     portion of the word definition:
    
77 
    78 LATEST .
    
79 134522384
    
80 LATEST 5 + C@ EMIT
    
81 L
    
82 LATEST 5 + HERE C@C!
    
83 HERE @ .
    
84 65356
    
85 HERE C@ EMIT
    
86 L
    
87 
    88     That's neat, but we can do one better by
    
89     copying the entire string. I'll reformat
    
90     the responses to make it even clearer:
    
91 
    92 LATEST 5 + HERE 6 CMOVE
    
93 HERE 0 + @ EMIT L
    
94 HERE 1 + @ EMIT A
    
95 HERE 2 + @ EMIT T
    
96 HERE 3 + @ EMIT E
    
97 HERE 4 + @ EMIT S
    
98 HERE 5 + @ EMIT T
    
99 
   100     Neat!
   
101 
   102     Next are return stack manipulation words. Forth
   
103     is surely unique in inviting programmers to monkey
   
104     about with the return stack for storing temporary
   
105     values or perform other clever tricks.
   
106     
   107         >R     move value from param stack to return stack
   
108         R>     move value from return stack to param stack
   
109         RSP@   get the actual address RSP points to
   
110         RSP!   set the address RSP points to
   
111         RDROP  move RSP to "pop" value and throw it away
   
112 
   113     According to Leo Brodie's Starting Forth, storing stuff
   
114     on the return stack should be safe to use when defining
   
115     a word. Outside of that, it'll likely cause a crash.
   
116 
   117 : store-add >R + R> ;
   
118 1 2 3 store-add . .
   
119 33
   
120 
   121     That works. Stows the 3 from the param stack on the return
   
122     stack, adds the 1 and 2 from the param stack and puts the
   
123     resulting 3 onto the param stack, restores the 3 from the
   
124     return stack back to the param stack.
   
125 
   126     We can look at the address of the return stack pointer (RSP).
   
127     Which is currently equal to the top of the return stack
   
128     memory address, stored in constant R0:
   
129 
   130 RSP@ .
   
131 134530680
   
132 R0 .
   
133 134530680
   
134 
   135     This isn't a very good demonstration of setting RSP since
   
136     I'm setting it to the existing value:
   
137 
   138 RSP@ RSP!
   
139 
   140     Now let's see if we can "drop" the value on the return
   
141     stack:
   
142 
   143 RSP@ @ .
   
144 0
   
145 5 >R
   
146 RSP@ @ .
   
147 5
   
148 RDROP
   
149 RSP@ @ .
   
150 0
   
151 
   152     Yup!
   
153 
   154     Like the return stack, we can mess directly with the param
   
155     stack with two words:
   
156 
   157         DSP@ - fetch address of param ("data") stack pointer
   
158         DSP! - set address of param stack pointer
   
159 
   160     Let's view the DSP address:
   
161 
   162 DSP@ .
   
163 3221223824
   
164 
   165     And it should go lower when we push a value because it
   
166     grows "upward":
   
167 
   168 55
   
169 DSP@ .
   
170 
   171     We can view the value on the stack by fetching it from
   
172     the address:
   
173 
   174 3221223820
   
175 DSP@ @ .
   
176 55
   
177 
   178     Let's put another value on the stack. DSP will get lower.
   
179     And we can view the new value:
   
180 
   181 77
   
182 DSP@ .
   
183 3221223816
   
184 DSP@ @ .
   
185 77
   
186 
   187     Let's try setting DSP "back" to a higher address to point
   
188     to and view the previous value again:
   
189 
   190 DSP@ 4 + DSP!
   
191 DSP@ .
   
192 3221223820
   
193 DSP@ @ .
   
194 55
   
195 
   196     Neat!