Annotation of gforth/arch/r8c/prim.fs, revision 1.20
1.1 pazsan 1: \ r8c/m16c primitives
2:
3: \ Copyright (C) 2006 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: \ * Register using for r8c
22: \ Renesas Forth used for
23: \ R0 TOS oberstes Stackelement
24: \ R3 RP Returnstack Pointer
25: \ SP SP Stack Pointer
26: \ A1 IP Instruction Pointer
27: \ A0 W Arbeitsregister
28: \
29: \ * Memory ( use only one 64K-Page ): TBD
30: \ **************************************************************
31:
32:
33: start-macros
34: \ register definition
1.2 pazsan 35: ' R0L Alias tos.b
1.1 pazsan 36:
1.7 pazsan 37: \ hfs wichtig, damit der erste Befehl richtig compiliert wird
38: reset \ hfs
39:
1.1 pazsan 40: \ system depending macros
1.8 pazsan 41: : next1,
1.18 pazsan 42: [w] , r1 mov.w:g r3r1 jmpi.a ;
1.1 pazsan 43: : next,
44: [ip] , w mov.w:g
1.8 pazsan 45: # 2 , ip add.w:q next1, ;
1.1 pazsan 46: \ note that this is really for 8086 and 286, and _not_ intented to run
47: \ fast on a Pentium (Pro). These old chips load their code from real RAM
48: \ and do it slow, anyway.
49: \ If you really want to have a fast 16 bit Forth on modern processors,
50: \ redefine it as
51: \ : next, [ip] w mov, 2 # ip add, [w] jmp, ;
52:
53: end-macros
54:
55: unlock
1.2 pazsan 56: $0000 $FFFF region address-space
57: $C000 $4000 region rom-dictionary
1.5 pazsan 58: $0400 $0400 region ram-dictionary
1.2 pazsan 59: .regions
60: setup-target
1.1 pazsan 61: lock
62:
63: \ ==============================================================
64: \ rom starts with jump to GFORTH-kernel (must be at $0000 !!!)
65: \ ==============================================================
66: Label into-forth
67: # $ffff , ip mov.w:g \ ip will be patched
1.18 pazsan 68: # $0780 , sp ldc \ sp at $0600...$0700
1.13 pazsan 69: # $07FE , rp mov.w:g \ rp at $0700...$07FE
1.9 pazsan 70: # $0F , $E3 mov.b:g
71: # $0F , $E1 mov.b:g
1.16 pazsan 72: Label mem-init
1.18 pazsan 73: $01 , $0A bset:g
74: $00 , $05 bset:g \ open data RAM
75: $01 , $0A bclr:g
1.9 pazsan 76: Label clock-init \ default is 125kHz/8
1.18 pazsan 77: $00 , $0A bset:g
1.10 pazsan 78: # $28 , $07 mov.b:g
1.9 pazsan 79: # $08 , $06 mov.b:g
1.16 pazsan 80: AHEAD THEN
1.18 pazsan 81: 2 , $0C bclr:g
1.9 pazsan 82: # $00 , $08 mov.b:g \ set to 20MHz
1.18 pazsan 83: $00 , $0A bclr:g
1.5 pazsan 84: Label uart-init
1.13 pazsan 85: # $27 , $B0 mov.b:g \ hfs
86: # $8105 , $A8 mov.w:g \ ser1: 9600 baud, 8N1 \ hfs
1.10 pazsan 87: # $0500 , $AC mov.w:g \ hfs
1.14 pazsan 88: Label lcd-init
1.18 pazsan 89: $02 , $0A bset:g
1.14 pazsan 90: # $FD , $E2 mov.b:g
91: next,
1.1 pazsan 92: End-Label
93:
94:
95: \ ==============================================================
96: \ GFORTH minimal primitive set
97: \ ==============================================================
98: \ inner interpreter
1.19 pazsan 99: align
100:
1.1 pazsan 101: Code: :docol
102: \ ': dout, \ only for debugging
103: # -2 , rp add.w:q
1.7 pazsan 104: w , r1 mov.w:g
1.1 pazsan 105: rp , w mov.w:g ip , [w] mov.w:g
1.7 pazsan 106: # 4 , r1 add.w:q r1 , ip mov.w:g
1.1 pazsan 107: next,
108: End-Code
109:
1.19 pazsan 110: align
1.1 pazsan 111:
1.4 pazsan 112: Code: :docon
113: \ '2 dout, \ only for debugging
114: tos push.w:g
1.10 pazsan 115: 4 [w] , tos mov.w:g
1.4 pazsan 116: next,
117: End-Code
118:
1.19 pazsan 119: align
120:
1.8 pazsan 121: Code: :dovalue
122: \ '2 dout, \ only for debugging
123: tos push.w:g
1.10 pazsan 124: 4 [w] , w mov.w:g [w] , tos mov.w:g
1.8 pazsan 125: next,
1.4 pazsan 126: End-Code
127:
1.19 pazsan 128: align
129:
1.13 pazsan 130: Code: :dofield
131: 4 [w] , tos add.w:g
132: next,
133: end-code
134:
1.19 pazsan 135: align
136:
1.9 pazsan 137: Code: :dodefer
1.10 pazsan 138: \ # $05 , $E1 mov.b:g
139: 4 [w] , w mov.w:g [w] , w mov.w:g
1.9 pazsan 140: next1,
141: End-Code
1.8 pazsan 142:
1.19 pazsan 143: align
144:
1.1 pazsan 145: Code: :dodoes ( -- pfa ) \ get pfa and execute DOES> part
146: \ '6 dout, \ only for debugging
1.8 pazsan 147: \ # $06 , $E1 mov.b:g
148: tos push.w:g
149: w , tos mov.w:g # 4 , tos add.w:q
1.20 ! pazsan 150: # -2 , rp add.w:q 2 [w] , r1 mov.w:g
1.13 pazsan 151: rp , w mov.w:g ip , [w] mov.w:g
1.20 ! pazsan 152: r1 , ip mov.w:g
1.1 pazsan 153: next, \ execute does> part
1.5 pazsan 154: End-Code
1.19 pazsan 155:
156: $C0FE here - allot
1.5 pazsan 157:
1.19 pazsan 158: Code: :dovar
159: \ '2 dout, \ only for debugging
160: tos push.w:g
161: # 4 , w add.w:q
162: w , tos mov.w:g
163: next,
164: End-Code
165:
166: \ program flow
1.1 pazsan 167: Code ;s ( -- ) \ exit colon definition
168: \ '; dout, \ only for debugging
169: rp , w mov.w:g # 2 , rp add.w:q
170: [w] , ip mov.w:g
171: next,
172: End-Code
173:
174: Code execute ( xt -- ) \ execute colon definition
175: \ 'E dout, \ only for debugging
1.10 pazsan 176: \ # $07 , $E1 mov.b:g
1.8 pazsan 177: tos , w mov.w:g \ copy tos to w
178: tos pop.w:g \ get new tos
179: next1,
1.1 pazsan 180: End-Code
181:
1.10 pazsan 182: Code ?branch ( f -- ) \ jump on f=0
1.7 pazsan 183: # 2 , ip add.w:q
1.10 pazsan 184: tos , tos tst.w 0= IF -2 [ip] , ip mov.w:g THEN
1.11 pazsan 185: tos pop.w:g
1.2 pazsan 186: next,
1.1 pazsan 187: End-Code
188:
1.10 pazsan 189: Code (for) ( n -- r:0 r:n )
190: # -4 , rp add.w:q rp , w mov.w:g
191: r3 , 2 [w] mov.w:g
192: tos , [w] mov.w:g
193: tos pop.w:g
194: next,
195: End-Code
196:
197: Code (?do) ( n -- r:0 r:n )
198: # 2 , ip add.w:q
199: # -4 , rp add.w:q rp , w mov.w:g
200: tos , [w] mov.w:g
201: r1 pop.w:g
202: r1 , 2 [w] mov.w:g
203: tos pop.w:g
204: [w] , r1 sub.w:g
205: 0= IF -2 [ip] , ip mov.w:g THEN
206: next,
207: End-Code
208:
209: Code (do) ( n -- r:0 r:n )
210: # -4 , rp add.w:q rp , w mov.w:g
211: tos , [w] mov.w:g
212: tos pop.w:g
213: tos , 2 [w] mov.w:g
214: tos pop.w:g
215: next,
216: End-Code
217:
218: Code (next) ( -- )
219: # 2 , ip add.w:q
220: rp , w mov.w:g [w] , r1 mov.w:g
221: # -1 , r1 add.w:q r1 , [w] mov.w:g
222: u>= IF -2 [ip] , ip mov.w:g THEN
223: next,
224: End-Code
225:
226: Code (loop) ( -- )
227: # 2 , ip add.w:q
228: rp , w mov.w:g [w] , r1 mov.w:g
229: # 1 , r1 add.w:q r1 , [w] mov.w:g
230: 2 [w] , r1 sub.w:g
231: 0<> IF -2 [ip] , ip mov.w:g THEN
232: next,
233: End-Code
1.1 pazsan 234:
235: \ memory access
236: Code @ ( addr -- n ) \ read cell
1.2 pazsan 237: tos , w mov.w:g [w] , tos mov.w:g
1.1 pazsan 238: next,
239: End-Code
240:
241: Code ! ( n addr -- ) \ write cell
1.2 pazsan 242: tos , w mov.w:g tos pop.w:g tos , [w] mov.w:g
243: tos pop.w:g
244: next,
245: End-Code
246:
247: Code c@ ( addr -- n ) \ read cell
248: tos , w mov.w:g tos , tos xor.w [w] , tos.b mov.b:g
249: next,
250: End-Code
251:
252: Code c! ( n addr -- ) \ write cell
253: tos , w mov.w:g tos pop.w:g tos.b , [w] mov.b:g
254: tos pop.w:g
255: next,
256: End-Code
257:
258: \ arithmetic and logic
259: Code + ( n1 n2 -- n3 ) \ addition
260: r1 pop.w:g
261: r1 , tos add.w:g
262: next,
263: End-Code
264:
265: Code - ( n1 n2 -- n3 ) \ addition
266: r1 pop.w:g
267: tos , r1 sub.w:g
268: r1 , tos mov.w:g
269: next,
270: End-Code
271:
272: Code and ( n1 n2 -- n3 ) \ addition
273: r1 pop.w:g
274: r1 , tos and.w:g
275: next,
276: End-Code
277:
278: Code or ( n1 n2 -- n3 ) \ addition
279: r1 pop.w:g
280: r1 , tos or.w:g
281: next,
282: End-Code
283:
284: Code xor ( n1 n2 -- n3 ) \ addition
285: r1 pop.w:g
286: r1 , tos xor.w
287: next,
288: End-Code
289:
290: \ moving datas between stacks
291: Code r> ( -- n ; R: n -- )
292: tos push.w:g
293: rp , w mov.w:g
294: [w] , tos mov.w:g
1.7 pazsan 295: # 2 , rp add.w:q \ ? hfs
1.1 pazsan 296: next,
297: End-Code
298:
1.2 pazsan 299: Code >r ( n -- ; R: -- n )
1.7 pazsan 300: # -2 , rp add.w:q \ ? hfs
1.2 pazsan 301: rp , w mov.w:g
302: tos , [w] mov.w:g
303: tos pop.w:g
304: next,
305: End-Code
306:
1.10 pazsan 307: Code rdrop ( R:n -- )
308: # 2 , rp add.w:q \ ? hfs
309: next,
310: End-Code
311:
312: Code unloop ( R:n -- )
313: # 4 , rp add.w:q \ ? hfs
314: next,
315: End-Code
316:
1.1 pazsan 317: \ datastack and returnstack address
318: Code sp@ ( -- sp ) \ get stack address
1.2 pazsan 319: tos push.w:g
320: sp , tos stc
321: next,
322: End-Code
1.1 pazsan 323:
324: Code sp! ( sp -- ) \ set stack address
1.2 pazsan 325: tos , sp ldc
326: tos pop.w:g
327: next,
1.1 pazsan 328: End-Code
329:
330: Code rp@ ( -- rp ) \ get returnstack address
1.2 pazsan 331: tos push.w:g
332: rp , tos mov.w:g
1.1 pazsan 333: next,
334: End-Code
335:
336: Code rp! ( rp -- ) \ set returnstack address
1.2 pazsan 337: tos , rp mov.w:g
338: tos pop.w:g
339: next,
340: End-Code
1.1 pazsan 341:
1.2 pazsan 342: Code branch ( -- ) \ unconditional branch
343: [ip] , ip mov.w:g
344: next,
1.1 pazsan 345: End-Code
346:
1.2 pazsan 347: Code lit ( -- n ) \ inline literal
348: tos push.w:g
349: [ip] , tos mov.w:g
1.3 pazsan 350: # 2 , ip add.w:q
1.2 pazsan 351: next,
1.1 pazsan 352: End-Code
353:
1.2 pazsan 354: Code: :doesjump
355: end-code
1.1 pazsan 356:
357: \ ==============================================================
358: \ usefull lowlevel words
359: \ ==============================================================
360: \ word definitions
361:
362:
363: \ branch and literal
364:
365: \ data stack words
366: Code dup ( n -- n n )
1.3 pazsan 367: tos push.w:g
1.1 pazsan 368: next,
369: End-Code
370:
371: Code 2dup ( d -- d d )
1.3 pazsan 372: r1 pop.w:g
373: r1 push.w:g
374: tos push.w:g
375: r1 push.w:g
1.1 pazsan 376: next,
377: End-Code
378:
379: Code drop ( n -- )
1.3 pazsan 380: tos pop.w:g
1.1 pazsan 381: next,
382: End-Code
383:
384: Code 2drop ( d -- )
1.3 pazsan 385: tos pop.w:g
386: tos pop.w:g
1.1 pazsan 387: next,
388: End-Code
389:
390: Code swap ( n1 n2 -- n2 n1 )
1.5 pazsan 391: r1 pop.w:g
392: tos push.w:g
393: r1 , tos mov.w:g
1.1 pazsan 394: next,
395: End-Code
396:
397: Code over ( n1 n2 -- n1 n2 n1 )
1.5 pazsan 398: tos , r1 mov.w:g
399: tos pop.w:g
400: tos push.w:g
401: r1 push.w:g
1.1 pazsan 402: next,
403: End-Code
404:
405: Code rot ( n1 n2 n3 -- n2 n3 n1 )
1.5 pazsan 406: tos , r1 mov.w:g
1.7 pazsan 407: r3 pop.w:g
1.5 pazsan 408: tos pop.w:g
1.7 pazsan 409: r3 push.w:g
1.5 pazsan 410: r1 push.w:g
1.7 pazsan 411: r3 , r3 xor.w
1.1 pazsan 412: next,
413: End-Code
414:
415: Code -rot ( n1 n2 n3 -- n3 n1 n2 )
1.5 pazsan 416: tos , r1 mov.w:g
417: tos pop.w:g
1.7 pazsan 418: r3 pop.w:g
1.5 pazsan 419: r1 push.w:g
1.7 pazsan 420: r3 push.w:g
421: r3 , r3 xor.w
1.1 pazsan 422: next,
423: End-Code
424:
425:
426: \ return stack
427: Code r@ ( -- n ; R: n -- n )
1.5 pazsan 428: tos push.w:g
429: rp , w mov.w:g
430: [w] , tos mov.w:g
1.1 pazsan 431: next,
432: End-Code
433:
434:
435: \ arithmetic
436:
437: Code um* ( u1 u2 -- ud ) \ unsigned multiply
1.7 pazsan 438: rp , r3 mov.w:g
1.5 pazsan 439: r2 pop.w:g
440: r2 , r0 mulu.w:g
441: r0 push.w:g
442: r2 , tos mov.w:g
1.7 pazsan 443: r3 , rp mov.w:g
444: r3 , r3 xor.w
1.5 pazsan 445: next,
1.1 pazsan 446: End-Code
447:
1.16 pazsan 448: Code m* ( u1 u2 -- ud ) \ unsigned multiply
449: rp , r3 mov.w:g
450: r2 pop.w:g
451: r2 , r0 mul.w:g
452: r0 push.w:g
453: r2 , tos mov.w:g
454: r3 , rp mov.w:g
455: r3 , r3 xor.w
456: next,
457: End-Code
458:
1.1 pazsan 459: Code um/mod ( ud u -- r q ) \ unsiged divide
1.7 pazsan 460: rp , r3 mov.w:g
1.5 pazsan 461: tos , r1 mov.w:g
462: r2 pop.w:g
463: tos pop.w:g
464: r1 divu.w
465: r2 push.w:g
1.7 pazsan 466: r3 , rp mov.w:g
467: r3 , r3 xor.w
1.5 pazsan 468: next,
1.1 pazsan 469: End-Code
470:
471: \ shift
472: Code 2/ ( n1 -- n2 ) \ arithmetic shift right
1.18 pazsan 473: # -1 , tos sha.w
474: \ # -1 , r1h mov.b:q
475: \ r1h , tos sha.w
1.1 pazsan 476: next,
477: End-Code
478:
479: Code lshift ( n1 n2 -- n3 ) \ shift n1 left n2 bits
1.7 pazsan 480: \ tos.b , r1h mov.w:g
1.14 pazsan 481: tos.b , r1h mov.b:g \ ? hfs
482: tos pop.w:g
483: r1h , tos shl.w
484: next,
1.1 pazsan 485: End-Code
486:
487: Code rshift ( n1 n2 -- n3 ) \ shift n1 right n2 bits
1.7 pazsan 488: \ tos.b , r1h mov.w:g
1.14 pazsan 489: tos.b , r1h mov.b:g \ ? hfs
490: r1h neg.b
491: tos pop.w:g
492: r1h , tos shl.w
1.1 pazsan 493: next,
494: End-Code
495:
496: \ compare
497: Code 0= ( n -- f ) \ Test auf 0
1.5 pazsan 498: tos , tos tst.w
1.18 pazsan 499: 0= IF # -1 , tos mov.w:q next,
500: THEN # 0 , tos mov.w:q next,
1.1 pazsan 501: next,
502: End-Code
503:
1.10 pazsan 504: Code 0< ( n -- f ) \ Test auf 0
505: tos , tos tst.w
1.18 pazsan 506: 0< IF # -1 , tos mov.w:q next,
507: THEN # 0 , tos mov.w:q next,
1.10 pazsan 508: next,
509: End-Code
510:
1.1 pazsan 511: Code = ( n1 n2 -- f ) \ Test auf Gleichheit
1.5 pazsan 512: r1 pop.w:g
513: r1 , tos sub.w:g
1.18 pazsan 514: 0= IF # -1 , tos mov.w:q next,
515: THEN # 0 , tos mov.w:q next,
1.1 pazsan 516: End-Code
517:
1.16 pazsan 518: ' = alias u=
519:
1.10 pazsan 520: Code u< ( n1 n2 -- f ) \ Test auf Gleichheit
521: r1 pop.w:g
522: r1 , tos sub.w:g
1.18 pazsan 523: u> IF # -1 , tos mov.w:q next,
524: THEN # 0 , tos mov.w:q next,
1.10 pazsan 525: End-Code
526:
527: Code u> ( n1 n2 -- f ) \ Test auf Gleichheit
528: r1 pop.w:g
529: r1 , tos sub.w:g
1.18 pazsan 530: u< IF # -1 , tos mov.w:q next,
531: THEN # 0 , tos mov.w:q next,
1.10 pazsan 532: End-Code
533:
1.3 pazsan 534: Code (key) ( -- char ) \ get character
1.5 pazsan 535: tos push.w:g
1.18 pazsan 536: BEGIN 3 , $AD btst:g 0<> UNTIL
1.13 pazsan 537: $AE , tos mov.w:g
1.3 pazsan 538: next,
539: End-Code
540:
541: Code (emit) ( char -- ) \ output character
1.18 pazsan 542: BEGIN 1 , $AD btst:g 0<> UNTIL
1.7 pazsan 543: tos.b , $AA mov.b:g
1.5 pazsan 544: tos pop.w:g
545: next,
1.3 pazsan 546: End-Code
547:
1.1 pazsan 548: \ additon io routines
549: Code (key?) ( -- f ) \ check for read sio character
1.5 pazsan 550: tos push.w:g
1.18 pazsan 551: 3 , $AD btst:g
552: 0<> IF # -1 , tos mov.w:q next,
553: THEN # 0 , tos mov.w:q next,
1.1 pazsan 554: End-Code
555:
556: Code emit? ( -- f ) \ check for write character to sio
1.5 pazsan 557: tos push.w:g
1.18 pazsan 558: 1 , $AD btst:g
559: 0<> IF # -1 , tos mov.w:q next,
560: THEN # 0 , tos mov.w:q next,
1.1 pazsan 561: End-Code
562:
1.14 pazsan 563: \ Useful code for R8C
564:
1.18 pazsan 565: Code btst ( b# addr -- f ) \ check for bit set in addr
566: tos , w mov.w:g # 3 , w shl.w
567: r1 pop.w:g r1 , w add.w:g [w] btst:g
568: 0<> IF # -1 , tos mov.w:q next,
569: THEN # 0 , tos mov.w:q next,
570: End-Code
571:
572: Code bset ( b# addr -- ) \ set bit in addr
573: tos , w mov.w:g # 3 , w shl.w
574: r1 pop.w:g r1 , w add.w:g [w] bset:g
575: tos pop.w:g next,
576: End-Code
577:
578: Code bclr ( b# addr -- ) \ clr bit in addr
579: tos , w mov.w:g # 3 , w shl.w
580: r1 pop.w:g r1 , w add.w:g [w] bclr:g
581: tos pop.w:g next,
582: End-Code
583:
1.16 pazsan 584: Code us ( n -- ) \ n microseconds delay
585: BEGIN AHEAD THEN AHEAD THEN
586: r1 , r1 mov.w:g
587: # -1 , tos add.w:q 0= UNTIL
1.14 pazsan 588: tos pop.w:g
589: next,
590: end-code
1.16 pazsan 591:
592: : ms ( n -- ) 0 ?DO &1000 us LOOP ;
1.14 pazsan 593:
594: $E0 Constant port0
595: $E1 Constant port1
596:
597: : led! port1 c! ;
1.16 pazsan 598: : >lcd ( 4bit -- )
599: 1+ dup port0 c! dup 8 + port0 c! 1 us port0 c!
600: &40 us ;
1.14 pazsan 601: : lcdctrl! ( n -- )
602: dup $F0 and >lcd
603: 4 lshift >lcd
1.16 pazsan 604: &100 us ;
605: : lcdemit ( n -- ) &100 us
1.14 pazsan 606: dup $F0 and 4 + >lcd
607: 4 lshift 4 + >lcd
1.16 pazsan 608: &250 us ;
1.14 pazsan 609: : lcdtype bounds ?DO I c@ lcdemit LOOP ;
1.16 pazsan 610: : lcdpage $01 lcdctrl! &15 ms ;
1.14 pazsan 611: : lcdcr $C0 lcdctrl! ;
612: : lcdinit ( -- )
1.20 ! pazsan 613: &20 ms $33 lcdctrl! 5 ms $20 >lcd
1.16 pazsan 614: &5 ms $28 lcdctrl!
615: &1 ms $0C lcdctrl!
616: &1 ms lcdpage ;
1.18 pazsan 617: : ?flash BEGIN $1B7 c@ 1 and 1 = UNTIL ;
618: : flashc! ( c addr -- ) $40 over c! c! ?flash ;
1.20 ! pazsan 619: : flash! ( x addr -- ) 2dup flashc! >r 8 rshift r> 1+ flashc! ;
1.18 pazsan 620: : flash-off ( addr -- ) $20 over c! $D0 swap c! ?flash ;
621: : flash-enable ( -- ) $1b7 c! 3 $1b7 c! 0 $1b5 c! 2 $1b5 c! ;
622: : r8cboot ( -- ) flash-enable lcdinit s" Gforth EC R8C" lcdtype boot ;
1.14 pazsan 623: ' r8cboot >body $C002 !
1.18 pazsan 624:
1.3 pazsan 625: : (bye) ( 0 -- ) \ back to DOS
626: drop ;
1.1 pazsan 627:
628: : bye ( -- ) 0 (bye) ;
629:
1.3 pazsan 630: : x@+/string ( addr u -- addr' u' c )
631: over c@ >r 1 /string r> ;
1.18 pazsan 632:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>