RfD - Memory access v3 ====================== History ======= 20160806 Revision 3 by Bernd Paysan, rewrite again, this time as library 20100621 fix typos: 'H' -> 'W'. 20100620 minor wordsmithing. 20100619 New subsection in Rationale for the Solution for case of fixed width elements greater than cell width; reorganization of subsections, Additonal Remarks, and A.18; replace LSBs with "least significant bits"; replaced specs for BFIELD: WFIELD: and LFIELD: 20100616 Wordsmithing. 20100615 Removed the optional sign field in naming convention; revised problem statement, solution statement, and added section on the rationale for the solution. 20100301 Updated after discussion on groups and lists, Changed word names to those used by Mitch Bradley as they have more precedence than those originally proposed. 20100225 Corrections to section numbering, Corrections to reference implementation, Added Josh Grams unit tests, Moved L words to EXT. 20100224 Revised reference implementation 20090923 Restored B@ and B!. 20090921 Forth200x review release. 20090902 Forth200x review update. 20090829 First writing according to the Proposals Process as described in the Draft 200x Standard. Problem ======= ANS Standard Forth lacks a way of accessing memory elements of a fixed width, and with specified byte ordering, in a portable way. Such words are needed by Forth progams to share data between applications in the same or different systems. Examples include, 1. transferring data between systems or applications which use data values of a size smaller than the Forth system cell width, 2. transferring data over protocols that define byte order, e.g. TCP/IP is big- endian and USB is little-endian, and 3. compiling code for systems using a byte order different from the host system. Therefore, a standard set of words providing memory access to fixed width, byte order-specified elements are needed to support Forth application development in areas such as data acquisition and control, network communications, and development of cross-compilers. Many existing Forth implementations provide a way of accessing some fixed width elements in native byte ordering, but no standard naming convention is used. Implementations providing for access to elements with specific byte-ordering are less common, and no standard naming convention is used. The previous proposal was rejected due to combinatorial explosion of the number of words; the proposal actually had only a limited amount of words, but that also limited the functionality. This proposal factors out byte order swap and sign extension. Even a relatively simple compiler can combine two or three of these words into one if the processor is capable of doing the two or three things required in one go. Solution ======== A library is proposed, the MEMORY-ACCESS library, to provide portable memory access words for memory access of common multiples of bytes. A char is assumed to be one byte, so byte accesses are done with C@ and C!. The following prefixes are used for multibyte values: 1 byte characters: c 2 byte words: w 4 byte longs: l, or ld on 16 bit systems 8 byte extended word: x, or xd on 32 bit systems, or xq on 16 bit systems All actual memory access words access the memory in host byte order and return an unsigned quantity. If you want to sign extend, use c>s for bytes, w>s for words, or l>s for longs. If you want a different byte order, be converts the data type to/from big endian, and le to/from little endian. If you need both sign extend and byte order change, first change the byte order and then sign extend. Example: W@ WBE W>S to fetch a signed 16 bit number in big endian byte order. On systems with small cell size, longs and extended words can not be represented in one cell on the stack; if these systems want to access 32 and 64 bit data portably use ld, xd (for down to 32 bit) or xq as prefix. If the cell size is big enough to fit the data, l and x prefixed words are available, too, providing a trade-off between portability and speed; note that on systems with smaller cell size, l and x words (and xd on 16 bits) may result in data loss. Since the proposal can be implemented in standard Forth, it is a library, not a wordset. Proposal ======== xx. The optional Memory-Access library xx.1 Introduction ----------------- All memory access operations in this standard library assume the following two conditions: 1. It is assumed one address unit can contain at least 8 bits [and 1 CHARS = 1] 2. For address units larger than 8 bits, each address unit contains one byte stored in the eight least significant bits. Additional bits shall be ignored by the fetch operations, and should be set to zero by the store operations. On the stack, all the bytes are packed together into single, double, or quad number, leaving the unused bits to the most significant bit as zero. The words in this word list generally take the form: [] where: size: C for 8 bit byte W for 16 bit word L for 32 bit long-word LD for 32 bit long-word as double X for 64 bit extended-word XD for 64 bit extended-word as double XQ for 64 bit extended-word as quad action: !, @ or , with the usual meaning BE or LE for converting to/from big/little endian >S, >D, or >Q for sign extending to 1/2/4 cell(s) Systems with multiple address spaces, e.g. Harvard architectures and cross-compilers often require an address space indicator. Data space is the default, using any other address space is outside the scope of this standard. Address space names that have been used include: address-space: C code space R register space T target address space in cross-compiler J JTAG or debug link The endian conversion words work by flipping the bytes, so they work in both ways: convert from native to a specific order and back. The word for the native order is always a noop, so these words can also be used to test the curent byte order: 1 DUP WBE = is true for big endian systems, and false for little endian systems. This is a standard library, as it can be fully implemented in standard Forth [with the environmental restriction of 1 CHARS = 1]. Implementers may provide performance tuned versions of this library. xx.2 Additional terms --------------------- big-endian: The most significant byte of a multi-byte value is stored at the lowest memory address. This is also known as network order. little-endian: The least significant byte of a multi-byte value is stored at the lowest memory address. native order: The byte ordering for multi-byte values which suits the system architecture. (See big-endian and little-endian.) xx.6 Glossary ------------- xx.6.1 Memory-Access words -------------------------- xx.6.1.---- C>S "c-extend" MEMORY-ACCESS ( c -- n ) Sign-extend the 8 bit value c. xx.6.1.---- W! "w-store" MEMORY-ACCESS ( x addr -- ) Store the 16 least significant bits of x at addr in native order irrespective of alignment. In systems where the address unit is larger than 16 bits, the upper bits are set to zero. xx.6.1.---- W, "w-comma" MEMORY-ACCESS ( x -- ) Reserve 16 bits of data space and store the 16 least significant bits of x in them in native order irrespective of alignment. xx.6.1.---- W>S "w-extend" MEMORY-ACCESS ( x -- n ) Sign-extend the 16 bit value x. xx.6.1.---- W@ "w-fetch" MEMORY-ACCESS ( addr -- x ) Fetch the 16 least significant bits of x from addr in native order irrespective of alignment. If the cell size is greater than 16 bits, the result is zero-extended. xx.6.1.---- WALIGN "w-align" MEMORY-ACCESS ( -- ) If the data-space pointer is not 16-bit aligned, reserve enough space to align it. See: 3.3.3 Data space, 3.3.3.1 Address alignment. xx.6.1.---- WALIGNED "w-aligned" MEMORY-ACCESS ( addr1 -- addr2 ) Addr2 is the first 16-bit aligned address greater than or equal to addr1. See: 3.3.3.1 Address alignment, xx.6.1.---- WALIGN. xx.6.1.---- WFIELD: "w-field-colon" MEMROY-ACCESS ( n1 "name" -- n2 ) Skip leading space delimiters. Parse /name/ delimited by a space. /Offset/ is the first 16-bit word aligned value greater than or equal to n1. n2 = offset + 2 bytes. Create a definition for /name/ with the execution semantics given below. /name/ Execution: ( a-addr1 -- a-addr2 ) Add the /offset/ calculated during the compile time action to a-addr1 giving the 16-bit aligned address a-addr2. See: 10.6.2.---- BEGIN-STRUCTURE, A.10.6.---- BEGIN-STRUCTURE, A.10.6.2.---- FIELD: xx.6.1.---- WLE "w-little-endian" MEMORY-ACCESS ( n1 -- n2 ) Convert n1 to/from little endian byte order to native byte order xx.6.1.---- WBE "w-big-endian" MEMORY-ACCESS ( n1 -- n2 ) Convert n1 to/from big endian byte order to native byte order xx.6.2 Memory-Access extension words ------------------------------------ xx.6.1.---- L! "l-store" MEMORY-ACCESS EXT ( x addr -- ) Store the 32 least significant bits of x at addr in native order irrespective of alignment. In systems where the address unit is larger than 32 bits, the upper bits are set to zero. xx.6.1.---- L, "l-comma" MEMORY-ACCESS EXT ( x -- ) Reserve 32 bits of data space and store the 32 least significant bits of x in them in native order irrespective of alignment. xx.6.1.---- L>S "l-extend" MEMORY-ACCESS EXT ( x -- n ) Sign-extend the 32 bit value x. xx.6.1.---- L@ "l-fetch" MEMORY-ACCESS EXT ( addr -- x ) Fetch the 32 least significant bits of x from addr in native order irrespective of alignment. If the cell size is greater than 32 bits, the result is zero-extended. xx.6.1.---- LALIGN "l-align" MEMORY-ACCESS EXT ( -- ) If the data-space pointer is not 32-bit aligned, reserve enough space to align it. See: 3.3.3 Data space, 3.3.3.1 Address alignment. xx.6.1.---- LALIGNED "l-aligned" MEMORY-ACCESS EXT ( addr1 -- addr2 ) Addr2 is the first 32-bit aligned address greater than or equal to addr1. See: 3.3.3.1 Address alignment, xx.6.1.---- LALIGN. xx.6.1.---- LBE "l-big-endian" MEMORY-ACCESS EXT ( x1 -- x2 ) Convert x1 to/from big endian byte order to native byte order xx.6.1.---- LD! "l-store" MEMORY-ACCESS EXT ( xd addr -- ) Store the 32 least significant bits of xd at addr in native order irrespective of alignment. In systems where the address unit is larger than 32 bits, the upper bits are set to zero. xx.6.1.---- LD, "l-comma" MEMORY-ACCESS EXT ( xd -- ) Reserve 32 bits of data space and store the 32 least significant bits of xd in them in native order irrespective of alignment. xx.6.1.---- LD@ "l-fetch" MEMORY-ACCESS EXT ( addr -- xd ) Fetch the 32 least significant bits of xd from addr in native order irrespective of alignment. If the cell size is greater than 16 bits, the result is zero-extended. xx.6.1.---- LDBE "ld-big-endian" MEMORY-ACCESS EXT ( xd1 -- xd2 ) Convert xd1 to/from big endian byte order to native byte order xx.6.1.---- LDLE "ld-little-endian" MEMORY-ACCESS EXT ( xd1 -- xd2 ) Convert xd1 to/from little endian byte order to native byte order xx.6.1.---- LFIELD: "l-field-colon" MEMORY-ACCESS EXT ( n1 "name" -- n2 ) Skip leading space delimiters. Parse /name/ delimited by a space. /Offset/ is the first 16-bit word aligned value greater than or equal to n1. n2 = offset + 4 bytes. Create a definition for /name/ with the execution semantics given below. /name/ Execution: ( a-addr1 -- a-addr2 ) Add the /offset/ calculated during the compile time action to a-addr1 giving the 16-bit aligned address a-addr2. See: 10.6.2.---- BEGIN-STRUCTURE, A.10.6.---- BEGIN-STRUCTURE, A.10.6.2.---- FIELD: xx.6.1.---- LLE "l-little-endian" MEMORY-ACCESS EXT ( n1 -- n2 ) Convert n1 to/from little endian byte order to native byte order xx.6.1.---- X! "x-store" MEMORY-ACCESS EXT ( x addr -- ) Store the 64 least significant bits of x at addr in native order irrespective of alignment. In systems where the address unit is larger than 64 bits, the upper bits are set to zero. xx.6.1.---- X, "x-comma" MEMORY-ACCESS EXT ( x -- ) Reserve 64 bits of data space and store the 64 least significant bits of x in them in native order irrespective of alignment. xx.6.1.---- X@ "x-fetch" MEMORY-ACCESS EXT ( addr -- x ) Fetch the 64 least significant bits of x from addr in native order irrespective of alignment. If the cell size is greater than 64 bits, the result is zero-extended. xx.6.1.---- XALIGN "x-align" MEMORY-ACCESS EXT ( -- ) If the data-space pointer is not 64-bit aligned, reserve enough space to align it. See: 3.3.3 Data space, 3.3.3.1 Address alignment. xx.6.1.---- XALIGNED "x-aligned" MEMORY-ACCESS EXT ( addr1 -- addr2 ) Addr2 is the first 64-bit aligned address greater than or equal to addr1. See: 3.3.3.1 Address alignment, xx.6.1.---- XALIGN. xx.6.1.---- XBE "x-big-endian" MEMORY-ACCESS EXT ( x1 -- x2 ) Convert x1 to/from big endian byte order to native byte order xx.6.1.---- XDBE "xd-big-endian" MEMORY-ACCESS EXT ( xd1 -- xd2 ) Convert xd1 to/from big endian byte order to native byte order xx.6.1.---- XDLE "xd-little-endian" MEMORY-ACCESS EXT ( xd1 -- xd2 ) Convert xd1 to/from little endian byte order to native byte order xx.6.1.---- XFIELD: "x-field-colon" MEMORY-ACCESS EXT ( n1 "name" -- n2 ) Skip leading space delimiters. Parse /name/ delimited by a space. /Offset/ is the first 64-bit word aligned value greater than or equal to n1. n2 = offset + 8 bytes. Create a definition for /name/ with the execution semantics given below. /name/ Execution: ( a-addr1 -- a-addr2 ) Add the /offset/ calculated during the compile time action to a-addr1 giving the 16-bit aligned address a-addr2. See: 10.6.2.---- BEGIN-STRUCTURE, A.10.6.---- BEGIN-STRUCTURE, A.10.6.2.---- FIELD: xx.6.1.---- XLE "x-little-endian" MEMORY-ACCESS EXT ( x1 -- x2 ) Convert x1 to/from little endian byte order to native byte order xx.6.1.---- XQBE "xq-big-endian" MEMORY-ACCESS EXT ( xq1 -- xq2 ) Convert xq1 to/from big endian byte order to native byte order xx.6.1.---- XQLE "xq-little-endian" MEMORY-ACCESS EXT ( xq1 -- xq2 ) Convert xq1 to/from little endian byte order to native byte order A.xx The optional Memory-Access word set ======================================== A.xx.1 ------ When operating on data larger than an address unit, memory operations shall be capable of unaligned operation, e.g. when fetching a 32 bit item from a non 32-bit aligned address, the operation will succeed. For cell addressed machines which use an address unit larger than 8 bits, it is assumed that the upper part of a cell is simply ignored. This proposal makes no attempt to deal with packing of bytes for memory efficiency. Providing that other operations such as TYPE produce the expected result, the implementation may deal with packing of data as it sees fit. However, the model of one byte per cell will always work with least implementation complexity. A.xx.2 ------ Data transferred between systems may represent signed or unsigned numbers or composite structures. No assumption of the number representation for signed numbers is made in this proposal. Transformation of fixed width signed data to cell width values and vice-versa are operations which are assumed to be handled by a set of words not specified in this proposal. A.xx.3 ------ A Forth program frequently has to transfer data over protocols that define the byte order of the data being transferred. Data transfer standards exist that are big-endian, e.g. TCP/IP, and little-endian, e.g. USB. This forces us to make a clear distinction between big- endian, little-endian and native order. Should a program ever need to detect the native order of the system, it can do so by using the following code: $1234 PAD ! PAD C@ $34 = or $1234 DUP WLE = This is true when the program is running on a little-endian system and false otherwise. A.xx.4 ------ Systems shall not implement words from the extended words section if such words result in a loss of information due to the system cell width. For example, L@ is specified to fetch a 32-bit value from memory into a single cell. It is impossible to implement L@ on a 16-bit Forth system without loss of information. All words not in the extended words section can be implemented without loss of information on any ANS Forth system having a valid cell width. A.xx.5 ------ BFIELD: WFIELD: and LFIELD: align the data pointer to the host systems preferred alignment. +FIELD can be used to define unaligned data fields. Reference Implementation ======================== This implementation makes three assumptions: 1. It is working on a byte addressed system. 2. A character is stored as a byte. 3. The cell size is either 2, 4 or 8 bytes. The reference implementation can be loaded onto a system that already contains some words of the memory library, it will then use the system words. This library uses the following words from CORE : Constant : >in @ >r postpone IF r> drop BEGIN + source = WHILE 0= UNTIL THEN ELSE ! ; 2drop swap 1+ cells < c@ lshift or dup and rshift over negate from CORE-EXT : parse pad nip from CORE-EXT-2012 : parse-name from BLOCK-EXT : \ from FILE : ( from FILE-EXT : refill from SEARCH : wordlist get-current set-current get-order set-order from SEARCH-EXT : previous from TOOLS-EXT : [IF] [ELSE] [THEN] from TOOLS-EXT-2012 : [defined] Synonym \ memory access words \ this file is in the public domain, it's just the reference \ implementation. Assumes byte addressed access, power of 2 bytes \ per cell \ helper words for conditional compile wordlist constant redef: get-current redef: set-current : : ( "name" -- ) \ conditional define >in @ >r postpone [defined] IF r> drop BEGIN ';' parse + source + = WHILE refill 0= UNTIL THEN ELSE r> >in ! : THEN ; : synonym ( "name" "oldname" -- ) \ conditional synonym >in @ >r postpone [defined] IF r> drop parse-name 2drop ELSE r> >in ! synonym THEN ; set-current get-order redef: swap 1+ set-order : noop ( -- ) ; \ does nothing \ helper words for byte swap : w>< ( w -- w' ) dup #8 rshift $FF and swap $FF and 8 lshift or ; 1 cells #4 < 0= [IF] : l>< ( l -- l' ) dup #16 rshift $FFFF and w>< swap $FFFF and w>< #16 lshift or ; : ld>< ( ld -- ld' ) drop l>< 0 ; 1 cells #8 < 0= [IF] : x>< ( x -- x' ) dup #32 rshift $FFFFFFFF and l>< swap $FFFFFFFF and l>< #32 lshift or ; : xd>< ( xd -- xd' ) drop x>< 0 ; [ELSE] : xd>< ( x -- x' ) l>< swap l>< ; [THEN] : xq>< ( xd -- xd' ) 2drop xd>< $0. ; [ELSE] : ld>< ( ld -- ld' ) w>< swap w>< ; : xq>< ( xq -- xq' ) l>< 2swap l>< ; [THEN] \ helper words for combining/splitting; endian-dependent byte swap 1 pad ! pad c@ 1 = [IF] \ little endian : cc>w ( b1 b2 -- w ) #8 lshift or ; : w>cc ( w -- b1 b2 ) dup $FF and swap #8 rshift ; synonym wbe w>< synonym wle noop 1 cells #4 < 0= [IF] : ww>l ( w1 w2 -- l ) #16 lshift or ; : l>ww ( l -- w1 w2 ) dup $FFFF and swap #16 rshift ; 1 cells #8 < 0= [IF] : ll>x ( l1 l2 -- x ) #32 lshift or ; : x>ll ( x -- l1 l2 ) dup $FFFFFFFF and swap #32 rshift ; synonym xbe x>< synonym xle noop [ELSE] synonym ll>xd noop ( l1 l2 -- dx ) synonym xd>ll noop ( l1 l2 -- dx ) [THEN] synonym lbe l>< synonym lle noop synonym xdbe xd>< synonym xdle noop synonym ldbe ld>< synonym ldle noop synonym xqbe xq>< synonym xqle noop [ELSE] synonym ww>dl noop ( l1 l2 -- dx ) synonym dl>ww noop ( dx -- l1 l2 ) synonym ll>qx noop ( dl1 dl2 -- qx ) synonym qx>ll noop ( qx -- dl1 dl2 ) synonym ldbe ld>< synonym ldle noop synonym xqbe xq>< synonym xqle noop [THEN] [ELSE] \ big endian : cc>w ( b1 b2 -- w ) swap #8 lshift or ; : w>cc ( w -- b1 b2 ) dup $FF and swap #8 rshift swap ; synonym wle w>< synonym wbe noop 1 cells #4 < 0= [IF] : ww>l ( w1 w2 -- l ) swap #16 lshift or ; : l>ww ( l -- w1 w2 ) dup $FFFF and swap #16 rshift swap ; 1 cells #8 < 0= [IF] : ll>x ( l1 l2 -- x ) swap #32 lshift or ; : x>ll ( x -- l1 l2 ) dup $FFFFFFFF and swap #32 rshift swap ; synonym xle x>< synonym xbe noop [ELSE] synonym ll>xd swap ( l1 l2 -- dx ) synonym xd>ll swap ( l1 l2 -- dx ) [THEN] synonym lle l>< synonym lbe noop synonym xdle xd>< synonym xdbe noop synonym ldle ld>< synonym ldbe noop synonym xqle xq>< synonym xqbe noop [ELSE] synonym ww>ld swap ( l1 l2 -- dx ) synonym ld>ww swap ( l1 l2 -- dx ) synonym ll>xq 2swap ( dl1 dl2 -- qx ) synonym xq>ll 2swap ( dl1 dl2 -- qx ) synonym ldle ld>< synonym ldbe noop synonym xqle xq>< synonym xqbe noop [THEN] [THEN] \ actual words for memory access : w@ ( addr -- w ) dup c@ swap 1+ c@ cc>w ; : w! ( w addr -- ) >r w>cc r@ c! r> 1+ c! ; : w, ( w -- ) here w! 2 allot ; 1 cells #4 < 0= [IF] : l@ ( addr -- l ) dup w@ swap 2 + w@ ww>l ; : l! ( l addr -- ) >r l>ww r@ w! r> 2 + w! ; : l, ( l -- ) here l! 4 allot ; [ELSE] : ld@ ( addr -- dl ) dup w@ swap 2 + w@ ww>ld ; : ld! ( dl addr -- ) >r ld>ww r@ w! r> 2 + w! ; : ld, ( dl -- ) here ld! 4 allot ; [THEN] 1 cells #8 < 0= [IF] : x@ ( addr -- x ) dup l@ swap 4 + l@ ll>x ; : x! ( x addr -- ) >r x>ll r@ l! r> 4 + l! ; : x, ( x -- ) here x! 8 allot ; [ELSE] 1 cells #4 < 0= [IF] : xd@ ( addr -- xd ) dup l@ swap 4 + l@ ll>xd ; : xd! ( xd addr -- ) >r xd>ll r@ l! r> 4 + l! ; : xd, ( xd -- ) here xd! 8 allot ; [ELSE] : xq@ ( addr -- x ) dup ld@ swap 4 + ld@ ll>xq ; : xq! ( x addr -- ) >r xq>ll r@ ld! r> 4 + ld! ; : xq, ( xq -- ) here xq! 8 allot ; [THEN] [THEN] \ alignments : *aligned ( addr n -- addr' ) tuck 1- + swap negate and ; : *align ( n -- ) here swap *aligned dp ! ; : walign ( -- ) 2 *align ; : waligned ( addr -- addr' ) 2 *aligned ; : wfield: ( offset -- offset' ) waligned 2 +field ; : lalign ( -- ) 4 *align ; : laligned ( addr -- addr' ) 4 *aligned ; : lfield: ( offset -- offset' ) laligned 4 +field ; : xalign ( -- ) 8 *align ; : xaligned ( addr -- addr' ) 8 *aligned ; : xfield: ( offset -- offset' ) xaligned 8 +field ; \ actual words for sign extension : mask>s ( x u -- n ) over and negate or ; : c>s ( c -- n ) $80 mask>s ; 1 cells 4 < 0= [IF] : w>s ( w -- n ) $8000 mask>s ; 1 cells 8 < 0= [IF] : l>s ( l -- n ) $80000000 mask>s ; [THEN] [THEN] \ compatibility with systems with smaller word size : xd! ( xd addr -- ) nip x! ; : xd@ ( addr -- xd ) x@ 0 ; : xd, ( xd -- ) drop x, ; : xq! ( xq addr -- ) nip nip xd! ; : xq@ ( addr -- xq ) xd@ $0. ; : xq, ( xq -- ) 2drop xd, ; : ld! ( ld addr -- ) nip l! ; : ld@ ( addr -- ld ) l@ 0 ; : ld, ( ld -- ) drop l, ; : xdle drop xle 0 ; : xdbe drop xbe 0 ; : ldle drop lle 0 ; : ldbe drop lbe 0 ; : xqle 2drop xdle #0. ; : xqbe 2drop xdbe #0. ; \ compatibility with systems with larger word size \ beware of information loss! : l@ ( addr -- l ) ld@ drop ; : l! ( l addr -- ) 0 swap ld! ; : l, ( l -- ) 0 ld, ; : xd@ ( addr -- x ) xq@ 2drop ; : xd! ( x addr -- ) $0. 2swap xq! ; : xd, ( x -- ) $0. xq, ; : x@ ( addr -- x ) xd@ drop ; : x! ( x addr -- ) 0 swap xd! ; : x, ( x -- ) 0 xd, ; previous Tests ===== tests require ttexter.fs Create readpad $01 c, $23 c, $45 c, $67 c, $89 c, $ab c, $cd c, $ef c, $10 buffer: writepad T{ readpad w@ wbe -> $0123 }T T{ readpad w@ wle -> $2301 }T 1 cells 4 < 0= [IF] T{ readpad l@ lbe -> $01234567 }T T{ readpad l@ lle -> $67452301 }T 1 cells 8 < 0= [IF] T{ readpad x@ xbe -> $0123456789ABCDEF }T T{ readpad x@ xle -> $EFCDAB8967452301 }T [ELSE] T{ readpad xd@ xdbe -> $0123456789ABCDEF. }T T{ readpad xd@ xdle -> $EFCDAB8967452301. }T [THEN] T{ readpad ld@ ldbe -> $01234567. }T T{ readpad ld@ ldle -> $67452301. }T 1 cells 4 < 0= [IF] T{ readpad xq@ xqbe -> $0123456789ABCDEF. $0. }T T{ readpad xq@ xqle -> $EFCDAB8967452301. $0. }T [ELSE] T{ readpad xq@ xqbe -> $89ABCDEF. $01234567. }T T{ readpad xq@ xqle -> $67452301. $EFCDAB89. }T [THEN] [ELSE] T{ readpad ld@ ldbe -> $01234567. }T T{ readpad ld@ ldle -> $67452301. }T T{ readpad xq@ xqbe -> $89ABCDEF. $01234567. }T T{ readpad xq@ xqle -> $67452301. $EFCDAB89. }T [THEN] \ more tests will come -- Bernd Paysan "If you want it done right, you have to do it yourself" net2o ID: kQusJzA;7*?t=uy@X}1GWr!+0qqp_Cn176t4(dQ* http://bernd-paysan.de/ Messages in this topic (2) __________________________________________________________________ ______ 1b. Re: 3rd RfD: memory access (standard library) Posted by: "Bernd Paysan" bernd.paysan@gmx.de berndpaysan Date: Sun Aug 7, 2016 2:13 pm ((PDT)) Am Sonntag, 7. August 2016, 23:02:18 CEST schrieb Bernd Paysan bernd.paysan@gmx.de [forth200x]: > A.xx.2 > ------ > > Data transferred between systems may represent signed or unsigned > numbers or composite structures. No assumption of the number > representation for signed numbers is made in this proposal. > Transformation of fixed width signed data to cell width values > and vice-versa are operations which are assumed to be handled by > a set of words not specified in this proposal. Looks like I forgot to change that paragraph. Should be Data transferred between systems may represent signed or unsigned numbers or composite structures. Signed numbers are stored as two's complement, and sign extended with C>S, W>S, and L>S. -- Bernd Paysan "If you want it done right, you have to do it yourself" net2o ID: kQusJzA;7*?t=uy@X}1GWr!+0qqp_Cn176t4(dQ* http://bernd-paysan.de/ Messages in this topic (2) ------------------------------------------------------------------ ------ Yahoo Groups Links <*> To visit your group on the web, go to: http://groups.yahoo.com/group/forth200x/ <*> Your email settings: Digest Email | Traditional <*> To change settings online go to: http://groups.yahoo.com/group/forth200x/join (Yahoo! ID required) <*> To change settings via email: forth200x-normal@yahoogroups.com forth200x-fullfeatured@yahoogroups.com <*> To unsubscribe from this group, send an email to: forth200x-unsubscribe@yahoogroups.com <*> Your use of Yahoo Groups is subject to: https://info.yahoo.com/legal/us/yahoo/utos/terms/ ------------------------------------------------------------------ ------