mirror of
https://git.sr.ht/~crc_/retroforth
synced 2024-11-16 19:48:56 +01:00
rx.muri: more comments and explainers in muri source
FossilOrigin-Name: 7e2eb1d5ab55b15d2fd183a3436c9f93346b4bb6e9da40d3dfa6c33ff16c593c
This commit is contained in:
parent
bc94e648a9
commit
b92e398e50
3 changed files with 73 additions and 3 deletions
|
@ -166,7 +166,9 @@ These are just simple accessor words to aid in overall readability.
|
|||
'.md [ 'text/markdown ] s:case
|
||||
'.htm [ 'text/html ] s:case
|
||||
'.html [ 'text/html ] s:case
|
||||
'.retro.html [ 'text/html ] s:case
|
||||
'.retro.html [ 'text/html ] s:case
|
||||
'.muri.html [ 'text/html ] s:case
|
||||
'.forth.html [ 'text/html ] s:case
|
||||
'.css [ 'text/css ] s:case
|
||||
'.c [ 'text/plain ] s:case
|
||||
'.h [ 'text/plain ] s:case
|
||||
|
|
|
@ -61,6 +61,7 @@ the token type and use `span`.
|
|||
$& [ 'ptr span ] case
|
||||
$$ [ 'char span ] case
|
||||
$` [ 'inst span ] case
|
||||
$\ [ 'inst span ] case
|
||||
$| [ 'defer span ] case
|
||||
$@ [ 'fetch span ] case
|
||||
$! [ 'store span ] case
|
||||
|
|
|
@ -1228,7 +1228,7 @@ useful. The major elements are:
|
|||
Nga has 30 instructions. These are:
|
||||
|
||||
0 nop 5 push 10 ret 15 fetch 20 div 25 zret
|
||||
1 lit 6 pop 11 eq 16 store 21 and 26 end
|
||||
1 lit 6 pop 11 eq 16 store 21 and 26 halt
|
||||
2 dup 7 jump 12 neq 17 add 22 or 27 ienum
|
||||
3 drop 8 call 13 lt 18 sub 23 xor 28 iquery
|
||||
4 swap 9 ccall 14 gt 19 mul 24 shift 29 iinvoke
|
||||
|
@ -1237,7 +1237,7 @@ The mnemonics allow for each name to be reduced to just two
|
|||
characters. In the same order as above:
|
||||
|
||||
0 .. 5 pu 10 re 15 fe 20 di 25 zr
|
||||
1 li 6 po 11 eq 16 st 21 an 26 en
|
||||
1 li 6 po 11 eq 16 st 21 an 26 ha
|
||||
2 du 7 ju 12 ne 17 ad 22 or 27 ie
|
||||
3 dr 8 ca 13 lt 18 su 23 xo 28 iq
|
||||
4 sw 9 cc 14 gt 19 mu 24 sh 29 ii
|
||||
|
@ -1278,6 +1278,21 @@ to actual instructions by the `i` word. As in the standard Muri
|
|||
assembler, the RETRO version uses `d` for decimal values and `r`
|
||||
for references to named functions.
|
||||
|
||||
The instructions table holds a hash value for each instruction
|
||||
name. Lookups return the index of the instruction, which will
|
||||
match the actual opcode. A value of zero marks the end of the
|
||||
table.
|
||||
|
||||
Hashes are the two ASCII values multiplied together. E.g., for
|
||||
`ha`, the hash is `#104 #97 *`.
|
||||
|
||||
This table can be regenerated using RETRO:
|
||||
|
||||
{ '.. 'li 'du 'dr 'sw 'pu 'po 'ju 'ca 'cc 're 'eq 'ne 'lt
|
||||
'gt 'fe 'st 'ad 'su 'mu 'di 'an 'or 'xo 'sh 'zr 'ha 'ie
|
||||
'iq 'ii }
|
||||
[ fetch-next swap fetch * 'd_ s:put n:put nl ] a:for-each
|
||||
|
||||
~~~
|
||||
: Instructions
|
||||
d 2116
|
||||
|
@ -1311,7 +1326,13 @@ d 10605
|
|||
d 11865
|
||||
d 11025
|
||||
d 0
|
||||
~~~
|
||||
|
||||
The `r` word resolves a reference and commas it into memory.
|
||||
|
||||
:r d:lookup d:xt fetch , ;
|
||||
|
||||
~~~
|
||||
: muri:r
|
||||
i lica....
|
||||
r d:lookup
|
||||
|
@ -1319,7 +1340,24 @@ i liadfe..
|
|||
d 1
|
||||
i liju....
|
||||
r comma
|
||||
~~~
|
||||
|
||||
The `i` word is used to assemble an instruction bundle and comma
|
||||
it into memory. This is basically:
|
||||
|
||||
:i
|
||||
dup get-opcode
|
||||
swap #2 + dup get-opcode
|
||||
swap #2 + dup get-opcode
|
||||
swap #2 + get-opcode
|
||||
#-24 shift swap #-16 shift +
|
||||
swap #-8 shift + + , ;
|
||||
|
||||
The actual implementation here is a bit different due to memory
|
||||
constraints, but the above should make it fairly clear how this
|
||||
works.
|
||||
|
||||
~~~
|
||||
: muri:i
|
||||
i dulica..
|
||||
r get-opcode
|
||||
|
@ -1343,12 +1381,28 @@ i shadad..
|
|||
|
||||
i liju....
|
||||
r comma
|
||||
~~~
|
||||
|
||||
I use `name-to-id` to do a very crude hash of the instruction
|
||||
names.
|
||||
|
||||
:name-to-id dup fetch swap #1 + fetch * ;
|
||||
:name-to-id fetch-next swap fetch * ;
|
||||
|
||||
~~~
|
||||
: name-to-id
|
||||
i dufeswli
|
||||
d 1
|
||||
i adfemure
|
||||
~~~
|
||||
|
||||
The `opcode-lookup` searches the `Instructions` table for a
|
||||
hashed opcode name.
|
||||
|
||||
:opcode-lookup
|
||||
repeat fetch-next 0; swap push over -eq? pop swap 0; drop again ;
|
||||
|
||||
~~~
|
||||
: opcode-lookup
|
||||
i lica....
|
||||
r fetch-next
|
||||
|
@ -1358,7 +1412,20 @@ i poswnepo
|
|||
i swzr....
|
||||
i drliju..
|
||||
r opcode-lookup
|
||||
~~~
|
||||
|
||||
Inner bits of the `i` word, factored out to save space. The
|
||||
interesting bit here is `get-opcode` which turns the returned
|
||||
address in the `Instructions` table to an opcode number.
|
||||
|
||||
:get-opcode
|
||||
name-to-id id-to-opcode &Instructions opcode-lookup
|
||||
nip &Instructions - #1 - ;
|
||||
|
||||
:muri:i
|
||||
swap #2 + dup get-opcode ;
|
||||
|
||||
~~~
|
||||
: (muri:i)
|
||||
i swliaddu
|
||||
d 2
|
||||
|
|
Loading…
Reference in a new issue