Questions on JIT...
Questions on JIT...
Regarding Just In Time Compilation for emulation of a full computer architecture: how does the code, once recompiled, run on the host PC, while still emulating the architecture being emulated?
For example: If I have some 6502 code, and then I translate it to x86 and run it on the host, how does that emulate the architecture being emulated? Isn't it being run on the host?
Can someone please point out the oh-so-obvious-point that I'm somehow missing?
Thanks.
For example: If I have some 6502 code, and then I translate it to x86 and run it on the host, how does that emulate the architecture being emulated? Isn't it being run on the host?
Can someone please point out the oh-so-obvious-point that I'm somehow missing?
Thanks.
C8H10N4O2 | #446691 | Trust the nodes.
keep in mind that the whole you translate the code from a platform to x86. You in fact only translate the behaviour. The architecture you simulate by handling the peripherals via memory mapped io etc. Thus every memory read or write you check whether if it is only memory or if it is hardware and take the appropriate action.
Author of COBOS
Hi,
Might be translated into:
Cheers,
Brendan
IIRC for 6502 there is no MMU (no segmentation and no paging) so it'd be faster to add the checks into the final code. For example, something like:os64dev wrote:keep in mind that the whole you translate the code from a platform to x86. You in fact only translate the behaviour. The architecture you simulate by handling the peripherals via memory mapped io etc. Thus every memory read or write you check whether if it is only memory or if it is hardware and take the appropriate action.
Code: Select all
LDX #$12
LDA $1234,X
STA $C000
Code: Select all
movzx ebx,byte 0x12
mov al,[EMU_RAM_base + 0x1234 + ebx]
test dword [EMU_CHIPSET_CONTROL], ENABLE_IO_BANK
je .l1
call EMU_IO_BANK_WRITE_ACCUMULATOR
jmp .l2
.l1:
mov [EMU_RAM_base + 0xC000],al
.l2:
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
So the translated assembly instructions don't really run on the machine. ie. they run on the processor, but affect the emulator's data. (stack, registers, etc.) This is what I had been getting confused. I thought they acted upon the actual machine's registers and such.
An implementation question, however. Let's say I have a function, t. t takes raw opcodes from the emulated data and translates them to assembly for the host PC. How to go about assembling them? An external assembler? Or just program the x86 codes right into the program? (I'm thinking more towards the latter.)
A more minor question, however. How to execute assembled code from C? A function pointer to the code that is then called?
Thanks!
An implementation question, however. Let's say I have a function, t. t takes raw opcodes from the emulated data and translates them to assembly for the host PC. How to go about assembling them? An external assembler? Or just program the x86 codes right into the program? (I'm thinking more towards the latter.)
A more minor question, however. How to execute assembled code from C? A function pointer to the code that is then called?
Thanks!
C8H10N4O2 | #446691 | Trust the nodes.
For that, look at this IOCCC worst abuse of the rules entry. Think about how it works.Alboin wrote:A more minor question, however. How to execute assembled code from C? A function pointer to the code that is then called?
http://www.au.ioccc.org/1984/mullender.c
Ah, okay. I wasn't too far off.Candy wrote:For that, look at this IOCCC worst abuse of the rules entry. Think about how it works.Alboin wrote:A more minor question, however. How to execute assembled code from C? A function pointer to the code that is then called?
http://www.au.ioccc.org/1984/mullender.c
The entry used an array, but couldn't one use a function pointer that is directed at an array?
C8H10N4O2 | #446691 | Trust the nodes.
Implicitly, the symbol "main" is a function pointer to your entry point. I believe your compiler will complain though (nowadays compilers don't let you make main an array of shorts).Alboin wrote:Ah, okay. I wasn't too far off.Candy wrote:For that, look at this IOCCC worst abuse of the rules entry. Think about how it works.Alboin wrote:A more minor question, however. How to execute assembled code from C? A function pointer to the code that is then called?
http://www.au.ioccc.org/1984/mullender.c
The entry used an array, but couldn't one use a function pointer that is directed at an array?
i've been programming emulators for some while now even with dynamic recompilation. The basic concept is like so: you have an byte array of N size (lets say 4 KiB) and an current translation instruction pointer.
Then you have some helper functions to enter opcodes in the code buffer.
now you have to write a parser to parse the original machine code and translate them into host machine opcodes.. as an example i just put some nop instructions and a return statement.
I hope this explains roughly what you need to do. I've written an PSone emulator like this and it works well.
Code: Select all
unsigned char translateCode[4096];
unsigned int translateIP;
Code: Select all
void genOpcode(int opc) {
translateCode[translateIP++] = opc;
}
Code: Select all
void main(void){
translateIP = 0;
for(int i = 0; i < 4095; i++) {
genOpcode(0x90); //- insert a nop instruction (x86).
}
genOpcode(0xC3); //- insert a return instruction (x86).
//- now execute the 4095 nops and the return.
(void(*)(void))translateCode();
printf("done...");
}
Author of COBOS