World: r3wp
[rebcode] Rebcode discussion
older newer | first last |
BrianH 20-Feb-2007 [1771x2] | You can even do this incrementally by filling in the code block as you go along and fixing up the offsets in the BRAB block as you generate the code that they point to.. |
The code generator can be your default code too, so code will get generated on the fly. | |
Steeve 20-Feb-2007 [1773] | yep, i follow u |
BrianH 20-Feb-2007 [1774] | There is no reason that the generated rebcode need be in the same order in its block that the original code is in its context. The BRAB block adds a layer of indirection, making the memory virtual. |
Steeve 20-Feb-2007 [1775] | yes, i agree |
BrianH 20-Feb-2007 [1776] | If you generate it as you go along, the rebcode will be generated in the order that it is executed. |
Steeve 20-Feb-2007 [1777] | it's the case currently |
BrianH 20-Feb-2007 [1778] | If you keep the Z80 memory in a binary! and make changes to it, whenever code at an offset already covered by the BRAB block is modified you would change that offset in the BRAB block to the default and mark the associated section of the rebcode as free. That way the next time you branch to that offset it would retranslate the Z80 to rebcode and put that rebcode in the first free spot big enough. You could even break up your code into blocks of around the same size and branch between them, to reduce fragmentation. |
Steeve 20-Feb-2007 [1779] | hmmm |
BrianH 20-Feb-2007 [1780x3] | You will likely have some rebcode that corresponds to the same areas of Z80 memory more than once, but memory is cheap on every platform REBOL runs on, particularly compared to a Z80. |
You can have all of your generated code segments be added as snippets of the same length if you wrap them in a block surrounded by the same code. For that matter, only that code block would need to be changed when changing the generated rebcode. You could even handle the freelist with ease by swapping marker code into free areas. | |
That would handle fragmentation issues in your generated code block with ease. | |
Steeve 20-Feb-2007 [1783x3] | and if i include my snipset in conditionnal block s, i will not have to recalculate offset of segments ? |
or into a loop 1 block! ? | |
all snipsets will have the same relative offset | |
BrianH 20-Feb-2007 [1786] | Or an ift block! where the t value would be set by freelist settings or something. |
Steeve 20-Feb-2007 [1787x3] | yep |
it could be usefull to interrupt the execution at any point | |
after a break point for example | |
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 |
older newer | first last |