r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[rebcode] Rebcode discussion

BrianH
20-Feb-2007
[1790x2]
If you fill in the whole rebcode block with code snippets of fixed 
length and then just swap in the code blocks you want, you wouldn't 
even need to alter the BRAB block - you could just change the code 
block references. For that matter, multiple references to the same 
code block could be just that, rather than copies, saving memory.
The main code block could be generated too, and all of your Z80 rebcode 
could be generated, and you could do the assembly yourself during 
the generation using code based on the standard assembler.
Steeve
20-Feb-2007
[1792]
hmmm
BrianH
20-Feb-2007
[1793]
The important part to duplicate from the assembler is the binding 
code. You won't have to duplicate the label fixup code, as you will 
be doing your own fixups. You might want to use label statements 
as markers for your own purposes though.
Steeve
20-Feb-2007
[1794]
yep
BrianH
20-Feb-2007
[1795]
If you go with the fixed main code block prefilled with snippets, 
the unchanging length of that block would lend stability to the rebcode 
interpreter. REBOL tends to crash if modifications to code that it 
is running at the time increase the length of the code block enough 
to force a reallocation of that block.
Steeve
20-Feb-2007
[1796x2]
ok , noted
ok, noted
BrianH
20-Feb-2007
[1798]
If you have each snippet be just this:
    IFT []
    BRA top

then the size of the main code block could be minimized, and the 
state of the T flag at the beginning of each snippet could control 
conditional execution.
Steeve
20-Feb-2007
[1799]
if think i will choose this option
BrianH
20-Feb-2007
[1800x5]
Then, you would just change the reference to the block to be something 
else when you fill in the snippet.
All of the infrastructure code would be at the top of the main code 
block, and the code that gets called every time before the BRAB would 
be after a LABEL top statement. Any calculations that affect the 
pc would go in the generated rebcode blocks.
You would use the built-in assembler to fixup the top references 
at the end of every code snippet to the proper offsets.
This approach would end up with the size of your generated interpreter 
adding up to one 64k element block for the BRAB target block, one 
main block of 64k*4 + (some fixed number for overhead code) elements, 
and the size of any rebcode blocks generated from Z80 code between 
branches. Your source would be much smaller, or course.
Well, that's all I have time for right now. I hope I helped!
Steeve
20-Feb-2007
[1805]
many thanks
Coccinelle
22-Feb-2007
[1806]
Question Steeve, if you parse the Z80 opcode to produce rebcode, 
how do you handle Self Modifying Code  opcode, for example this one 
which is used to save a and restore it later :
   ld (Restore + 1), a
   .. (Do some stuff)
   Restore:	ld  a, 12h

This sample is a common optimization technic used in the 80's
Steeve
22-Feb-2007
[1807x2]
yeah yeah, that is not a problem anymore, i changed my way, now with 
rebcode i do pure emulation.
soon i will post a proto
Coccinelle
23-Feb-2007
[1809x3]
peut-être que cela te serait utile :
; Patch to rebcode assembler

; - Add setl opcode -> setl: ["Set variable to label offset (0 based 
offset)" word! word!]
; - very usefull to call sub routine

system/internal/rebcode*: make system/internal/rebcode* [
    fix-bl: func [block /local labels here label][
	    labels: make block! 16 
	    block-action: :fix-bl 
	    if debug? [print "=== Fixing binding and labels... ==="] 
	    parse block [
	        some [
	            here: 
	            subblock-rule (here/1: bind here/1 words) 
	            | 

             'label word! (here/1: bind here/1 words insert insert tail labels 
             here/2 index? here) 
                |
                'setl word! word!
	            | 
	            opcode-rule (here/1: bind here/1 words) 
	            | 
                skip (print "LA" error here)
	        ]
	    ] 
	    parse block [
	        some [
	            here: 
	            ['bra word! | 'brat word! | 'braf word!] (
	                fix-label labels at here 2 here 0
	            ) 
	            | 
	            'brab into [some word!] word! (
	                label: here/2 
	                forall label [
	                    fix-label labels label here -1
	                ]
	            ) 
	            | 
	            'brab word! word! (
	                fix-label labels at here 2 here -1
	            ) 
	            |
	            'setl word! word! (
	            	here/1: 'set
	            	here/1: bind here/1 words
	            	here/3: -1 + any [
	            		select labels to word! here/3

               error/with here join "Missing label '" [here/3 ":"]
            		]
	            )
	            | 
	            opcode-rule 
	            | 
                skip (print "ICI" error here)
	        ]
	    ]
    ]
	system/internal/assemble: func [
	    "REBCODE Assembler" 
	    body 
	    /local frame here do-blks labels tmp rule
	][
	    body: second :body 
	    fix-bl body
	]
]
Usefull to call sub routine :
test: rebcode [
	i [integer!]
	/local ret-ofs begin
][
label begin
	brab [lab-1 lab-2] i

label lab-1
	print "call from lab-1"
	setl ret-ofs ret-1
	bra sub
label ret-1
	print "returned to ret-1"
	exit

label lab-2
	print "call from lab-2"
	setl ret-ofs ret-2
	bra sub
label ret-2
	print "returned to ret-2"
	exit

label sub
	print "pass thru sub"
	brab begin ret-ofs
]
>> test 0
call from lab-1
pass thru sub
returned to ret-1
>> test 1
call from lab-2
pass thru sub
returned to ret-2
>>
Steeve
23-Feb-2007
[1812x6]
hum, i'm not sure of  the utility of your code. Currently,  the development 
of the Z80 virtual machine is achieved and is very simple.
label Start
xcv
label start
pickz op-code memory adress
brab [          ;list of opcode
	...
             ...
             LD_A_B
            ... 
] op-code
label LD_A_B set.i _a _b bra start
the new rebcode version, is several times faster than the old, i'm 
happy !,  and I did not convert the video emulation into rebcode 
yet  , so ,   I think that we will be able to play in a screen much 
larger while keeping fluidity.
i could share my work, is the Altme Filesharing  working ? i think 
not
BrianH
23-Feb-2007
[1818x2]
A direct interpreter, or I guess a tokenized interpreter using the 
original opcodes as tokens, which amounts to the same thing. Interesting. 
I suppose that would be simplest way to do it, and a threaded interpreter 
would be a little hard in rebcode because of the relative branches. 
Good job!
I notice that your example doesn't adjust the program counter - I 
assume that these adjustments are performed by your real code.
Steeve
23-Feb-2007
[1820]
yeah it was a sample, my code is a little more complex
BrianH
23-Feb-2007
[1821x2]
Your new version also deals with the too-many-words backwards-compatibility 
problem that the old approach had, by just having words for opcodes 
rather than addresses. It should also have much less memory overhead 
than my compiled suggestion, and not require generating the rebcode 
of the interpreter - it is probably hand-codeable.
Are all opcodes distinguishable by a single byte, or do you have 
a more complex instruction decoding process?
Steeve
23-Feb-2007
[1823x4]
current state of my work http://perso.orange.fr/rebol/code.r
op-code may be on several bytes
i use several brab in sequence
if needed
BrianH
23-Feb-2007
[1827x2]
Several branches for every instruction, but probably optimizable 
on a special-case basis. Definitely slower than compiled rebcode, 
but much less complex and without the compiler overhead, so perhaps 
not that much slower. Much more compatible with self-modifying code. 
Also likely more compatible with JIT-compiled rebcode when that happens. 
Some code-generation on your interpreter, but mostly hand-coded. 
Overall, nice.
Your VM is single-instance right now, but that won't be a problem 
until R3's threading. For now, multiple interpreters can be in different 
REBOL processes. I don't know enough about what you are interpreting 
to know whether that matters :)
Steeve
23-Feb-2007
[1829x2]
mostly Game roms
they don't need multi trheading
BrianH
23-Feb-2007
[1831]
Probably not, then. You might want to wrap this all in a context 
statement to capture the global variables you're using.
Steeve
23-Feb-2007
[1832x3]
currently i'm looking for a good implementation of DDA opcode (Decimal 
adjust for BDC numbers)
quite difficult
*BCD numbers
BrianH
23-Feb-2007
[1835]
BCD numbers in games?
Steeve
23-Feb-2007
[1836]
yes for displaying score or other human readable numbers
BrianH
23-Feb-2007
[1837]
That platform has BCD-based output opcodes? Surprising - most use 
integers and string conversion.
Steeve
23-Feb-2007
[1838x2]
i found one that uses a look-up table of 4096 entries... little big
yes but addition and substractions are performed on char! (byte)