Is it possible to make a ROM converter?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
1
down vote

favorite
1












Based on my understanding, an emulator is necessary because the machine with the emulator on it (say Windows), doesn't execute the same machine code as the target platform (6502, for example). So what an emulator does is it interprets the code line by line and executes it itself, similar to how an interpreter works.



With this in mind, would it be possible to create the equivalent of a compiler, that would convert (for example) a .PCE file into a .exe file, so that it could run on Windows without an emulator?










share|improve this question























  • You can write a program that could convert a ROM to an EXE, but it would just be bundling the emulator with the ROM in the same EXE file.
    – Ross Ridge
    1 hour ago






  • 2




    You would still need to include the emulator code somehow as you need to emulate the hardware of the target platform. So yes, I'm sure it would be possible to have a single .exe, but it would just be a combination of the emulator and the ROM data
    – bodgit
    1 hour ago










  • If you were working at only the CPU level, you could write a 'compiler' to convert 6502 instructions into the equivalent x86 instructions. This could work but gets flakier as complexity increases. You might be able to write a loop in 6502 that counts to 100 and exits, and 'compile' those instructions into x86 code that also counts to 100 and exits. But the moment you tried to 'print the results' you would become platform dependent, and now you need an I/O system, and now your 'compiler' doesn't work anymore.
    – Geo...
    1 hour ago














up vote
1
down vote

favorite
1












Based on my understanding, an emulator is necessary because the machine with the emulator on it (say Windows), doesn't execute the same machine code as the target platform (6502, for example). So what an emulator does is it interprets the code line by line and executes it itself, similar to how an interpreter works.



With this in mind, would it be possible to create the equivalent of a compiler, that would convert (for example) a .PCE file into a .exe file, so that it could run on Windows without an emulator?










share|improve this question























  • You can write a program that could convert a ROM to an EXE, but it would just be bundling the emulator with the ROM in the same EXE file.
    – Ross Ridge
    1 hour ago






  • 2




    You would still need to include the emulator code somehow as you need to emulate the hardware of the target platform. So yes, I'm sure it would be possible to have a single .exe, but it would just be a combination of the emulator and the ROM data
    – bodgit
    1 hour ago










  • If you were working at only the CPU level, you could write a 'compiler' to convert 6502 instructions into the equivalent x86 instructions. This could work but gets flakier as complexity increases. You might be able to write a loop in 6502 that counts to 100 and exits, and 'compile' those instructions into x86 code that also counts to 100 and exits. But the moment you tried to 'print the results' you would become platform dependent, and now you need an I/O system, and now your 'compiler' doesn't work anymore.
    – Geo...
    1 hour ago












up vote
1
down vote

favorite
1









up vote
1
down vote

favorite
1






1





Based on my understanding, an emulator is necessary because the machine with the emulator on it (say Windows), doesn't execute the same machine code as the target platform (6502, for example). So what an emulator does is it interprets the code line by line and executes it itself, similar to how an interpreter works.



With this in mind, would it be possible to create the equivalent of a compiler, that would convert (for example) a .PCE file into a .exe file, so that it could run on Windows without an emulator?










share|improve this question















Based on my understanding, an emulator is necessary because the machine with the emulator on it (say Windows), doesn't execute the same machine code as the target platform (6502, for example). So what an emulator does is it interprets the code line by line and executes it itself, similar to how an interpreter works.



With this in mind, would it be possible to create the equivalent of a compiler, that would convert (for example) a .PCE file into a .exe file, so that it could run on Windows without an emulator?







emulation nes compilers turbografx-16






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 2 mins ago









Raffzahn

40.2k492165




40.2k492165










asked 1 hour ago









Jack Kasbrack

18314




18314











  • You can write a program that could convert a ROM to an EXE, but it would just be bundling the emulator with the ROM in the same EXE file.
    – Ross Ridge
    1 hour ago






  • 2




    You would still need to include the emulator code somehow as you need to emulate the hardware of the target platform. So yes, I'm sure it would be possible to have a single .exe, but it would just be a combination of the emulator and the ROM data
    – bodgit
    1 hour ago










  • If you were working at only the CPU level, you could write a 'compiler' to convert 6502 instructions into the equivalent x86 instructions. This could work but gets flakier as complexity increases. You might be able to write a loop in 6502 that counts to 100 and exits, and 'compile' those instructions into x86 code that also counts to 100 and exits. But the moment you tried to 'print the results' you would become platform dependent, and now you need an I/O system, and now your 'compiler' doesn't work anymore.
    – Geo...
    1 hour ago
















  • You can write a program that could convert a ROM to an EXE, but it would just be bundling the emulator with the ROM in the same EXE file.
    – Ross Ridge
    1 hour ago






  • 2




    You would still need to include the emulator code somehow as you need to emulate the hardware of the target platform. So yes, I'm sure it would be possible to have a single .exe, but it would just be a combination of the emulator and the ROM data
    – bodgit
    1 hour ago










  • If you were working at only the CPU level, you could write a 'compiler' to convert 6502 instructions into the equivalent x86 instructions. This could work but gets flakier as complexity increases. You might be able to write a loop in 6502 that counts to 100 and exits, and 'compile' those instructions into x86 code that also counts to 100 and exits. But the moment you tried to 'print the results' you would become platform dependent, and now you need an I/O system, and now your 'compiler' doesn't work anymore.
    – Geo...
    1 hour ago















You can write a program that could convert a ROM to an EXE, but it would just be bundling the emulator with the ROM in the same EXE file.
– Ross Ridge
1 hour ago




You can write a program that could convert a ROM to an EXE, but it would just be bundling the emulator with the ROM in the same EXE file.
– Ross Ridge
1 hour ago




2




2




You would still need to include the emulator code somehow as you need to emulate the hardware of the target platform. So yes, I'm sure it would be possible to have a single .exe, but it would just be a combination of the emulator and the ROM data
– bodgit
1 hour ago




You would still need to include the emulator code somehow as you need to emulate the hardware of the target platform. So yes, I'm sure it would be possible to have a single .exe, but it would just be a combination of the emulator and the ROM data
– bodgit
1 hour ago












If you were working at only the CPU level, you could write a 'compiler' to convert 6502 instructions into the equivalent x86 instructions. This could work but gets flakier as complexity increases. You might be able to write a loop in 6502 that counts to 100 and exits, and 'compile' those instructions into x86 code that also counts to 100 and exits. But the moment you tried to 'print the results' you would become platform dependent, and now you need an I/O system, and now your 'compiler' doesn't work anymore.
– Geo...
1 hour ago




If you were working at only the CPU level, you could write a 'compiler' to convert 6502 instructions into the equivalent x86 instructions. This could work but gets flakier as complexity increases. You might be able to write a loop in 6502 that counts to 100 and exits, and 'compile' those instructions into x86 code that also counts to 100 and exits. But the moment you tried to 'print the results' you would become platform dependent, and now you need an I/O system, and now your 'compiler' doesn't work anymore.
– Geo...
1 hour ago










5 Answers
5






active

oldest

votes

















up vote
3
down vote



accepted










Note: This answer mainly focuses on the NES, since that's what I'm most familiar with.



Yes; this is called static recompilation or static binary translation, and it can be done -- jamulator by Andrew Kelly does it.



However, there are some serious challenges involved. Determining the behavior of a program by statically analyzing its code is in some cases provably impossible. Some of the problems faced when statically recompiling a retro video game ROM include:



How do we determine what parts of the ROM are executable code and what parts are data?



The "obvious" way to recompile a NES ROM is to take a single pass, reading a stream of 6502 instructions and outputting a stream of x86 instructions. However, the ROM also includes data bytes, which will produce garbage if interpreted as instructions. These garbage instructions should never be executed, since the program would never jump to that address, but the presence of non-instruction data poses two problems:



1) The program must be able to read its own ROM. This isn't really a hard problem at all; we just need to include an uncompiled copy of the ROM in the compiled program binary to read data bytes from.



2) We can't write a simple single-pass recompiler. Since instructions can be multiple bytes wide, if we try to recompile a block of non-executable data, we might end up misaligned when recompiling the next block of instructions. (As a simple (somewhat contrived) example, in 6502 machine code, the sequence of bytes 69 09 0A is ADC #09; ASL, while the sequence of bytes A5 69 09 0A is LDA $69; ORA #0A. The point at which we start executing drastically affects our results).



So this means we have to perform much more complex code analysis in order to determine the basic blocks of the program and compile them individually. jamulator does this by starting at the interrupt vectors and following all possible branches from there. However, this approach still has problems with:



Dynamic jumps



This is where the address to execute is computed at runtime. In some cases, the runtime-computed address can be looked up and the corresponding x86 code can be found. However, if the only way to access a basic block is via an indirect jump, the recompiler would likely have assumed that block was not executable code and thus not compiled it.



jamulator mitigates this problem using a hack: hard-coded support in the recompiler to recognize jump table implementations in specific games. This works, but is clearly not a general-purpose solution.



Bank switching



Although jamulator only supports NROM games, many NES games with more complicated mappers could switch regions of code and data in and out of the accessible address space. This means that each jump could go to dozens of different locations in the ROM, depending on which bank is mapped to that address at runtime.



Dynamically generated code/self-modifying code



Although this was uncommon for NES games due to the small amount of RAM, if I remember correctly C64 software would occasionally generate and execute code at runtime, or modify code mid-execution. This would be nearly impossible to statically predict.



Other hardware such as graphics and audio



The NES Picture Processing Unit and Audio Processing Unit still must be emulated. jamulator includes an emulator for the non-CPU hardware in a runtime library. The generated code detects writes to the memory addresses mapped to I/O operations and calls out to the appropriate runtime libraries.



However, since many NES games relied on precise timing between the CPU and PPU, the generated CPU code must count the number of NES clock cycles taken by the executed code. jamulator implements this relatively simply: after each NES instruction, it calls out to a runtime library to run the rest of the hardware for a specific number of cycles. This approach is simple to implement, but has a few disadvantages:



  • CPU writes don't quite happen on the exactly correct cycle relative to the rest of the hardware. The timing is only accurate to the nearest instruction, not the nearest cycle.

  • Emulating the PPU and APU between every set of CPU instructions greatly impairs performance, since the recompiler loses opportunities to remove, combine, or reorder instructions for better performance, and switching between tasks frequently harms the x86 CPU's cache performance and branch prediction accurately.

A more efficient (but much more complex) approach could predict the times at which synchronization is needed between the CPU and the rest of the hardware and use the predictions to switch between fast and cycle-accurate emulation modes.




Although static recompilation is often possible, it can be extremely difficult. jamulator sometimes falls back to interpretation when the game does something not properly handled by the static recompiler.



The accuracy of static recompilation could be improved by running the game inside of something like FCEUX's code-data logger, which emulates the game while recording the code paths it takes. Data from an actual run of the game can be used to greatly improve the accuracy of static recompilation. However, the "test run" recorded by the code-data logger must comprehensively exercise the possible code paths taken by the game in order to be useful.



Emulators of newer systems, such as the Dolphin Emulator (which emulates the GameCube and Wii) frequently use just-in-time compilation, where the emulator recompiles sections of the game's code at runtime. This generally provides the best of both worlds: we get the performance improvements of recompiled code, and the improved insight of being able to analyze the game's code at runtime.






share|improve this answer






















  • This is how answers should be written. 10/10
    – Jack Kasbrack
    24 mins ago






  • 1




    Well, to avoide a delicate first impression, it may be a good idea to preface this with a clear statement, that the machine emulation is still needed, which is usually the largest part of an emulator - and using recompiled code will raise the challenge, thus ending in an even more complicated process of emulation. Otherwise, nice source of information.
    – Raffzahn
    6 mins ago


















up vote
6
down vote













The problem is that the emulator is emulating a LOT more than just the CPU. So in addition to transpiling the 6502 code to Intel code (and don't think that's simple - making the timing come out right would be a fascinating problem), you also need to provide code (analogous to the standard libraries that any program uses) that provide an emulated I/O environment that the 6502 code can manipulate.



It'd be much easier to just bundle the emulator and program into one binary and ship that. This is what Ian Bogost did with A Slow Year - the 6502 binary is just wrapped up into a binary with the emulator.






share|improve this answer
















  • 1




    The question is also based upon a fundamental misunderstanding that the code in question exists in "lines" that can be compiled.
    – JdeBP
    1 hour ago










  • Okay, In what way?
    – Jack Kasbrack
    56 mins ago

















up vote
3
down vote













Whether or not it's possible isn't the only defining factor that goes into development. Keep in mind that the quality of an emulator is very much connected to it's ability to create TAS, Savestate, use RAMWatch, and so on, all of which would not be possible if the ROM was converted to a .EXE file. With this in mind, developers haven't been interested in creating such a thing, which is the very reason why it isn't "possible" with the knowledge that the community is likely to have.






share|improve this answer








New contributor




DrMeta is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
























    up vote
    1
    down vote













    Compiling the instructions of an arbitrary processor (e.g. a 6502) into code that will run on a modern PC should be pretty easy. After all, it's not far different from what's done by any just-in-time compiler for a language that's distributed as bytecode (e.g. Java, .NET, and so on) and simpler than a JIT compiler for a language that needs non-trivial parsing (e.g. Javascript). The easy way would be to use an existing code generator (e.g. LLVM or gcc) and just add a very simple front end that read the machine code and generated the appropriate intermediate instructions...



    There are three things that make this much more complex than it seems:



    • First, you'd need to emulate the hardware other than the CPU, so the graphics system, the audio system, etc. Along with this you'd need to provide a pre-translated version of any firmware that's expected to be present on your target system so that it can be linked in to the code you're compiling.


    • Second, you need to identify what parts of the ROM are actually instructions to be executed, and what parts are data (e.g. sprites, audio tracks, game level maps, etc). The data parts need to be handled differently -- ideally, translated into a more easily accessed format (especially multi-byte numbers, either integers or floating point, which could easily be in a format that the host processor doesn't natively understand).


    • Third, and possibly more interestingly, all of this may in fact be somewhat less legal than just using interpreted emulation. Many software and hardware vendors have granted permission to allow their code (either firmware or games) to be used in emulators, as long as they remain unchanged (e.g. I know that this is the situation with the ROMs for the Sinclair ZX Spectrum, which have been released under terms like these by their current copyright holder, Amstrad PLC). But recompiling it for a new system does change it. Even when copyright permission hasn't been granted, there are a variety of exceptions to copyright that allow minimal copying to be performed (e.g. copying the contents of a cartridge ROM onto disk for easier access) if that's necessary to make it work -- but recompiling isn't necessary, so even where there's no explicit licence grant available it may be less legal to recompile for a new architecture than just to emulate the old one. (I'm not a lawyer, so take this with a very large pinch of salt, but I have spent a reasonable amount of time learning about copyright law, and I'm pretty confident this position)





    share



























      up vote
      0
      down vote













      Not quite a complete answer; however, many emulators of the consoles like playstation and alike do in some sense the same you are asking about.



      Instead of precisely executing the code and precisely emulating the hardware, some typical code pieces (mostly connected with 3D transformations and rendering) are recognized as a whole and the end result is just inserted in the machine state or rendered using host 3D capabilities. The reason in doing so is probably lack of detailed hardware information and the speed of host CPU being not enough to emulate everything precilesy.





      share




















        Your Answer








        StackExchange.ready(function()
        var channelOptions =
        tags: "".split(" "),
        id: "648"
        ;
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function()
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled)
        StackExchange.using("snippets", function()
        createEditor();
        );

        else
        createEditor();

        );

        function createEditor()
        StackExchange.prepareEditor(
        heartbeatType: 'answer',
        convertImagesToLinks: false,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: null,
        bindNavPrevention: true,
        postfix: "",
        imageUploader:
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        ,
        noCode: true, onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        );



        );













         

        draft saved


        draft discarded


















        StackExchange.ready(
        function ()
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fretrocomputing.stackexchange.com%2fquestions%2f8121%2fis-it-possible-to-make-a-rom-converter%23new-answer', 'question_page');

        );

        Post as a guest






























        5 Answers
        5






        active

        oldest

        votes








        5 Answers
        5






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes








        up vote
        3
        down vote



        accepted










        Note: This answer mainly focuses on the NES, since that's what I'm most familiar with.



        Yes; this is called static recompilation or static binary translation, and it can be done -- jamulator by Andrew Kelly does it.



        However, there are some serious challenges involved. Determining the behavior of a program by statically analyzing its code is in some cases provably impossible. Some of the problems faced when statically recompiling a retro video game ROM include:



        How do we determine what parts of the ROM are executable code and what parts are data?



        The "obvious" way to recompile a NES ROM is to take a single pass, reading a stream of 6502 instructions and outputting a stream of x86 instructions. However, the ROM also includes data bytes, which will produce garbage if interpreted as instructions. These garbage instructions should never be executed, since the program would never jump to that address, but the presence of non-instruction data poses two problems:



        1) The program must be able to read its own ROM. This isn't really a hard problem at all; we just need to include an uncompiled copy of the ROM in the compiled program binary to read data bytes from.



        2) We can't write a simple single-pass recompiler. Since instructions can be multiple bytes wide, if we try to recompile a block of non-executable data, we might end up misaligned when recompiling the next block of instructions. (As a simple (somewhat contrived) example, in 6502 machine code, the sequence of bytes 69 09 0A is ADC #09; ASL, while the sequence of bytes A5 69 09 0A is LDA $69; ORA #0A. The point at which we start executing drastically affects our results).



        So this means we have to perform much more complex code analysis in order to determine the basic blocks of the program and compile them individually. jamulator does this by starting at the interrupt vectors and following all possible branches from there. However, this approach still has problems with:



        Dynamic jumps



        This is where the address to execute is computed at runtime. In some cases, the runtime-computed address can be looked up and the corresponding x86 code can be found. However, if the only way to access a basic block is via an indirect jump, the recompiler would likely have assumed that block was not executable code and thus not compiled it.



        jamulator mitigates this problem using a hack: hard-coded support in the recompiler to recognize jump table implementations in specific games. This works, but is clearly not a general-purpose solution.



        Bank switching



        Although jamulator only supports NROM games, many NES games with more complicated mappers could switch regions of code and data in and out of the accessible address space. This means that each jump could go to dozens of different locations in the ROM, depending on which bank is mapped to that address at runtime.



        Dynamically generated code/self-modifying code



        Although this was uncommon for NES games due to the small amount of RAM, if I remember correctly C64 software would occasionally generate and execute code at runtime, or modify code mid-execution. This would be nearly impossible to statically predict.



        Other hardware such as graphics and audio



        The NES Picture Processing Unit and Audio Processing Unit still must be emulated. jamulator includes an emulator for the non-CPU hardware in a runtime library. The generated code detects writes to the memory addresses mapped to I/O operations and calls out to the appropriate runtime libraries.



        However, since many NES games relied on precise timing between the CPU and PPU, the generated CPU code must count the number of NES clock cycles taken by the executed code. jamulator implements this relatively simply: after each NES instruction, it calls out to a runtime library to run the rest of the hardware for a specific number of cycles. This approach is simple to implement, but has a few disadvantages:



        • CPU writes don't quite happen on the exactly correct cycle relative to the rest of the hardware. The timing is only accurate to the nearest instruction, not the nearest cycle.

        • Emulating the PPU and APU between every set of CPU instructions greatly impairs performance, since the recompiler loses opportunities to remove, combine, or reorder instructions for better performance, and switching between tasks frequently harms the x86 CPU's cache performance and branch prediction accurately.

        A more efficient (but much more complex) approach could predict the times at which synchronization is needed between the CPU and the rest of the hardware and use the predictions to switch between fast and cycle-accurate emulation modes.




        Although static recompilation is often possible, it can be extremely difficult. jamulator sometimes falls back to interpretation when the game does something not properly handled by the static recompiler.



        The accuracy of static recompilation could be improved by running the game inside of something like FCEUX's code-data logger, which emulates the game while recording the code paths it takes. Data from an actual run of the game can be used to greatly improve the accuracy of static recompilation. However, the "test run" recorded by the code-data logger must comprehensively exercise the possible code paths taken by the game in order to be useful.



        Emulators of newer systems, such as the Dolphin Emulator (which emulates the GameCube and Wii) frequently use just-in-time compilation, where the emulator recompiles sections of the game's code at runtime. This generally provides the best of both worlds: we get the performance improvements of recompiled code, and the improved insight of being able to analyze the game's code at runtime.






        share|improve this answer






















        • This is how answers should be written. 10/10
          – Jack Kasbrack
          24 mins ago






        • 1




          Well, to avoide a delicate first impression, it may be a good idea to preface this with a clear statement, that the machine emulation is still needed, which is usually the largest part of an emulator - and using recompiled code will raise the challenge, thus ending in an even more complicated process of emulation. Otherwise, nice source of information.
          – Raffzahn
          6 mins ago















        up vote
        3
        down vote



        accepted










        Note: This answer mainly focuses on the NES, since that's what I'm most familiar with.



        Yes; this is called static recompilation or static binary translation, and it can be done -- jamulator by Andrew Kelly does it.



        However, there are some serious challenges involved. Determining the behavior of a program by statically analyzing its code is in some cases provably impossible. Some of the problems faced when statically recompiling a retro video game ROM include:



        How do we determine what parts of the ROM are executable code and what parts are data?



        The "obvious" way to recompile a NES ROM is to take a single pass, reading a stream of 6502 instructions and outputting a stream of x86 instructions. However, the ROM also includes data bytes, which will produce garbage if interpreted as instructions. These garbage instructions should never be executed, since the program would never jump to that address, but the presence of non-instruction data poses two problems:



        1) The program must be able to read its own ROM. This isn't really a hard problem at all; we just need to include an uncompiled copy of the ROM in the compiled program binary to read data bytes from.



        2) We can't write a simple single-pass recompiler. Since instructions can be multiple bytes wide, if we try to recompile a block of non-executable data, we might end up misaligned when recompiling the next block of instructions. (As a simple (somewhat contrived) example, in 6502 machine code, the sequence of bytes 69 09 0A is ADC #09; ASL, while the sequence of bytes A5 69 09 0A is LDA $69; ORA #0A. The point at which we start executing drastically affects our results).



        So this means we have to perform much more complex code analysis in order to determine the basic blocks of the program and compile them individually. jamulator does this by starting at the interrupt vectors and following all possible branches from there. However, this approach still has problems with:



        Dynamic jumps



        This is where the address to execute is computed at runtime. In some cases, the runtime-computed address can be looked up and the corresponding x86 code can be found. However, if the only way to access a basic block is via an indirect jump, the recompiler would likely have assumed that block was not executable code and thus not compiled it.



        jamulator mitigates this problem using a hack: hard-coded support in the recompiler to recognize jump table implementations in specific games. This works, but is clearly not a general-purpose solution.



        Bank switching



        Although jamulator only supports NROM games, many NES games with more complicated mappers could switch regions of code and data in and out of the accessible address space. This means that each jump could go to dozens of different locations in the ROM, depending on which bank is mapped to that address at runtime.



        Dynamically generated code/self-modifying code



        Although this was uncommon for NES games due to the small amount of RAM, if I remember correctly C64 software would occasionally generate and execute code at runtime, or modify code mid-execution. This would be nearly impossible to statically predict.



        Other hardware such as graphics and audio



        The NES Picture Processing Unit and Audio Processing Unit still must be emulated. jamulator includes an emulator for the non-CPU hardware in a runtime library. The generated code detects writes to the memory addresses mapped to I/O operations and calls out to the appropriate runtime libraries.



        However, since many NES games relied on precise timing between the CPU and PPU, the generated CPU code must count the number of NES clock cycles taken by the executed code. jamulator implements this relatively simply: after each NES instruction, it calls out to a runtime library to run the rest of the hardware for a specific number of cycles. This approach is simple to implement, but has a few disadvantages:



        • CPU writes don't quite happen on the exactly correct cycle relative to the rest of the hardware. The timing is only accurate to the nearest instruction, not the nearest cycle.

        • Emulating the PPU and APU between every set of CPU instructions greatly impairs performance, since the recompiler loses opportunities to remove, combine, or reorder instructions for better performance, and switching between tasks frequently harms the x86 CPU's cache performance and branch prediction accurately.

        A more efficient (but much more complex) approach could predict the times at which synchronization is needed between the CPU and the rest of the hardware and use the predictions to switch between fast and cycle-accurate emulation modes.




        Although static recompilation is often possible, it can be extremely difficult. jamulator sometimes falls back to interpretation when the game does something not properly handled by the static recompiler.



        The accuracy of static recompilation could be improved by running the game inside of something like FCEUX's code-data logger, which emulates the game while recording the code paths it takes. Data from an actual run of the game can be used to greatly improve the accuracy of static recompilation. However, the "test run" recorded by the code-data logger must comprehensively exercise the possible code paths taken by the game in order to be useful.



        Emulators of newer systems, such as the Dolphin Emulator (which emulates the GameCube and Wii) frequently use just-in-time compilation, where the emulator recompiles sections of the game's code at runtime. This generally provides the best of both worlds: we get the performance improvements of recompiled code, and the improved insight of being able to analyze the game's code at runtime.






        share|improve this answer






















        • This is how answers should be written. 10/10
          – Jack Kasbrack
          24 mins ago






        • 1




          Well, to avoide a delicate first impression, it may be a good idea to preface this with a clear statement, that the machine emulation is still needed, which is usually the largest part of an emulator - and using recompiled code will raise the challenge, thus ending in an even more complicated process of emulation. Otherwise, nice source of information.
          – Raffzahn
          6 mins ago













        up vote
        3
        down vote



        accepted







        up vote
        3
        down vote



        accepted






        Note: This answer mainly focuses on the NES, since that's what I'm most familiar with.



        Yes; this is called static recompilation or static binary translation, and it can be done -- jamulator by Andrew Kelly does it.



        However, there are some serious challenges involved. Determining the behavior of a program by statically analyzing its code is in some cases provably impossible. Some of the problems faced when statically recompiling a retro video game ROM include:



        How do we determine what parts of the ROM are executable code and what parts are data?



        The "obvious" way to recompile a NES ROM is to take a single pass, reading a stream of 6502 instructions and outputting a stream of x86 instructions. However, the ROM also includes data bytes, which will produce garbage if interpreted as instructions. These garbage instructions should never be executed, since the program would never jump to that address, but the presence of non-instruction data poses two problems:



        1) The program must be able to read its own ROM. This isn't really a hard problem at all; we just need to include an uncompiled copy of the ROM in the compiled program binary to read data bytes from.



        2) We can't write a simple single-pass recompiler. Since instructions can be multiple bytes wide, if we try to recompile a block of non-executable data, we might end up misaligned when recompiling the next block of instructions. (As a simple (somewhat contrived) example, in 6502 machine code, the sequence of bytes 69 09 0A is ADC #09; ASL, while the sequence of bytes A5 69 09 0A is LDA $69; ORA #0A. The point at which we start executing drastically affects our results).



        So this means we have to perform much more complex code analysis in order to determine the basic blocks of the program and compile them individually. jamulator does this by starting at the interrupt vectors and following all possible branches from there. However, this approach still has problems with:



        Dynamic jumps



        This is where the address to execute is computed at runtime. In some cases, the runtime-computed address can be looked up and the corresponding x86 code can be found. However, if the only way to access a basic block is via an indirect jump, the recompiler would likely have assumed that block was not executable code and thus not compiled it.



        jamulator mitigates this problem using a hack: hard-coded support in the recompiler to recognize jump table implementations in specific games. This works, but is clearly not a general-purpose solution.



        Bank switching



        Although jamulator only supports NROM games, many NES games with more complicated mappers could switch regions of code and data in and out of the accessible address space. This means that each jump could go to dozens of different locations in the ROM, depending on which bank is mapped to that address at runtime.



        Dynamically generated code/self-modifying code



        Although this was uncommon for NES games due to the small amount of RAM, if I remember correctly C64 software would occasionally generate and execute code at runtime, or modify code mid-execution. This would be nearly impossible to statically predict.



        Other hardware such as graphics and audio



        The NES Picture Processing Unit and Audio Processing Unit still must be emulated. jamulator includes an emulator for the non-CPU hardware in a runtime library. The generated code detects writes to the memory addresses mapped to I/O operations and calls out to the appropriate runtime libraries.



        However, since many NES games relied on precise timing between the CPU and PPU, the generated CPU code must count the number of NES clock cycles taken by the executed code. jamulator implements this relatively simply: after each NES instruction, it calls out to a runtime library to run the rest of the hardware for a specific number of cycles. This approach is simple to implement, but has a few disadvantages:



        • CPU writes don't quite happen on the exactly correct cycle relative to the rest of the hardware. The timing is only accurate to the nearest instruction, not the nearest cycle.

        • Emulating the PPU and APU between every set of CPU instructions greatly impairs performance, since the recompiler loses opportunities to remove, combine, or reorder instructions for better performance, and switching between tasks frequently harms the x86 CPU's cache performance and branch prediction accurately.

        A more efficient (but much more complex) approach could predict the times at which synchronization is needed between the CPU and the rest of the hardware and use the predictions to switch between fast and cycle-accurate emulation modes.




        Although static recompilation is often possible, it can be extremely difficult. jamulator sometimes falls back to interpretation when the game does something not properly handled by the static recompiler.



        The accuracy of static recompilation could be improved by running the game inside of something like FCEUX's code-data logger, which emulates the game while recording the code paths it takes. Data from an actual run of the game can be used to greatly improve the accuracy of static recompilation. However, the "test run" recorded by the code-data logger must comprehensively exercise the possible code paths taken by the game in order to be useful.



        Emulators of newer systems, such as the Dolphin Emulator (which emulates the GameCube and Wii) frequently use just-in-time compilation, where the emulator recompiles sections of the game's code at runtime. This generally provides the best of both worlds: we get the performance improvements of recompiled code, and the improved insight of being able to analyze the game's code at runtime.






        share|improve this answer














        Note: This answer mainly focuses on the NES, since that's what I'm most familiar with.



        Yes; this is called static recompilation or static binary translation, and it can be done -- jamulator by Andrew Kelly does it.



        However, there are some serious challenges involved. Determining the behavior of a program by statically analyzing its code is in some cases provably impossible. Some of the problems faced when statically recompiling a retro video game ROM include:



        How do we determine what parts of the ROM are executable code and what parts are data?



        The "obvious" way to recompile a NES ROM is to take a single pass, reading a stream of 6502 instructions and outputting a stream of x86 instructions. However, the ROM also includes data bytes, which will produce garbage if interpreted as instructions. These garbage instructions should never be executed, since the program would never jump to that address, but the presence of non-instruction data poses two problems:



        1) The program must be able to read its own ROM. This isn't really a hard problem at all; we just need to include an uncompiled copy of the ROM in the compiled program binary to read data bytes from.



        2) We can't write a simple single-pass recompiler. Since instructions can be multiple bytes wide, if we try to recompile a block of non-executable data, we might end up misaligned when recompiling the next block of instructions. (As a simple (somewhat contrived) example, in 6502 machine code, the sequence of bytes 69 09 0A is ADC #09; ASL, while the sequence of bytes A5 69 09 0A is LDA $69; ORA #0A. The point at which we start executing drastically affects our results).



        So this means we have to perform much more complex code analysis in order to determine the basic blocks of the program and compile them individually. jamulator does this by starting at the interrupt vectors and following all possible branches from there. However, this approach still has problems with:



        Dynamic jumps



        This is where the address to execute is computed at runtime. In some cases, the runtime-computed address can be looked up and the corresponding x86 code can be found. However, if the only way to access a basic block is via an indirect jump, the recompiler would likely have assumed that block was not executable code and thus not compiled it.



        jamulator mitigates this problem using a hack: hard-coded support in the recompiler to recognize jump table implementations in specific games. This works, but is clearly not a general-purpose solution.



        Bank switching



        Although jamulator only supports NROM games, many NES games with more complicated mappers could switch regions of code and data in and out of the accessible address space. This means that each jump could go to dozens of different locations in the ROM, depending on which bank is mapped to that address at runtime.



        Dynamically generated code/self-modifying code



        Although this was uncommon for NES games due to the small amount of RAM, if I remember correctly C64 software would occasionally generate and execute code at runtime, or modify code mid-execution. This would be nearly impossible to statically predict.



        Other hardware such as graphics and audio



        The NES Picture Processing Unit and Audio Processing Unit still must be emulated. jamulator includes an emulator for the non-CPU hardware in a runtime library. The generated code detects writes to the memory addresses mapped to I/O operations and calls out to the appropriate runtime libraries.



        However, since many NES games relied on precise timing between the CPU and PPU, the generated CPU code must count the number of NES clock cycles taken by the executed code. jamulator implements this relatively simply: after each NES instruction, it calls out to a runtime library to run the rest of the hardware for a specific number of cycles. This approach is simple to implement, but has a few disadvantages:



        • CPU writes don't quite happen on the exactly correct cycle relative to the rest of the hardware. The timing is only accurate to the nearest instruction, not the nearest cycle.

        • Emulating the PPU and APU between every set of CPU instructions greatly impairs performance, since the recompiler loses opportunities to remove, combine, or reorder instructions for better performance, and switching between tasks frequently harms the x86 CPU's cache performance and branch prediction accurately.

        A more efficient (but much more complex) approach could predict the times at which synchronization is needed between the CPU and the rest of the hardware and use the predictions to switch between fast and cycle-accurate emulation modes.




        Although static recompilation is often possible, it can be extremely difficult. jamulator sometimes falls back to interpretation when the game does something not properly handled by the static recompiler.



        The accuracy of static recompilation could be improved by running the game inside of something like FCEUX's code-data logger, which emulates the game while recording the code paths it takes. Data from an actual run of the game can be used to greatly improve the accuracy of static recompilation. However, the "test run" recorded by the code-data logger must comprehensively exercise the possible code paths taken by the game in order to be useful.



        Emulators of newer systems, such as the Dolphin Emulator (which emulates the GameCube and Wii) frequently use just-in-time compilation, where the emulator recompiles sections of the game's code at runtime. This generally provides the best of both worlds: we get the performance improvements of recompiled code, and the improved insight of being able to analyze the game's code at runtime.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 15 mins ago

























        answered 25 mins ago









        NobodyNada

        2,006725




        2,006725











        • This is how answers should be written. 10/10
          – Jack Kasbrack
          24 mins ago






        • 1




          Well, to avoide a delicate first impression, it may be a good idea to preface this with a clear statement, that the machine emulation is still needed, which is usually the largest part of an emulator - and using recompiled code will raise the challenge, thus ending in an even more complicated process of emulation. Otherwise, nice source of information.
          – Raffzahn
          6 mins ago

















        • This is how answers should be written. 10/10
          – Jack Kasbrack
          24 mins ago






        • 1




          Well, to avoide a delicate first impression, it may be a good idea to preface this with a clear statement, that the machine emulation is still needed, which is usually the largest part of an emulator - and using recompiled code will raise the challenge, thus ending in an even more complicated process of emulation. Otherwise, nice source of information.
          – Raffzahn
          6 mins ago
















        This is how answers should be written. 10/10
        – Jack Kasbrack
        24 mins ago




        This is how answers should be written. 10/10
        – Jack Kasbrack
        24 mins ago




        1




        1




        Well, to avoide a delicate first impression, it may be a good idea to preface this with a clear statement, that the machine emulation is still needed, which is usually the largest part of an emulator - and using recompiled code will raise the challenge, thus ending in an even more complicated process of emulation. Otherwise, nice source of information.
        – Raffzahn
        6 mins ago





        Well, to avoide a delicate first impression, it may be a good idea to preface this with a clear statement, that the machine emulation is still needed, which is usually the largest part of an emulator - and using recompiled code will raise the challenge, thus ending in an even more complicated process of emulation. Otherwise, nice source of information.
        – Raffzahn
        6 mins ago











        up vote
        6
        down vote













        The problem is that the emulator is emulating a LOT more than just the CPU. So in addition to transpiling the 6502 code to Intel code (and don't think that's simple - making the timing come out right would be a fascinating problem), you also need to provide code (analogous to the standard libraries that any program uses) that provide an emulated I/O environment that the 6502 code can manipulate.



        It'd be much easier to just bundle the emulator and program into one binary and ship that. This is what Ian Bogost did with A Slow Year - the 6502 binary is just wrapped up into a binary with the emulator.






        share|improve this answer
















        • 1




          The question is also based upon a fundamental misunderstanding that the code in question exists in "lines" that can be compiled.
          – JdeBP
          1 hour ago










        • Okay, In what way?
          – Jack Kasbrack
          56 mins ago














        up vote
        6
        down vote













        The problem is that the emulator is emulating a LOT more than just the CPU. So in addition to transpiling the 6502 code to Intel code (and don't think that's simple - making the timing come out right would be a fascinating problem), you also need to provide code (analogous to the standard libraries that any program uses) that provide an emulated I/O environment that the 6502 code can manipulate.



        It'd be much easier to just bundle the emulator and program into one binary and ship that. This is what Ian Bogost did with A Slow Year - the 6502 binary is just wrapped up into a binary with the emulator.






        share|improve this answer
















        • 1




          The question is also based upon a fundamental misunderstanding that the code in question exists in "lines" that can be compiled.
          – JdeBP
          1 hour ago










        • Okay, In what way?
          – Jack Kasbrack
          56 mins ago












        up vote
        6
        down vote










        up vote
        6
        down vote









        The problem is that the emulator is emulating a LOT more than just the CPU. So in addition to transpiling the 6502 code to Intel code (and don't think that's simple - making the timing come out right would be a fascinating problem), you also need to provide code (analogous to the standard libraries that any program uses) that provide an emulated I/O environment that the 6502 code can manipulate.



        It'd be much easier to just bundle the emulator and program into one binary and ship that. This is what Ian Bogost did with A Slow Year - the 6502 binary is just wrapped up into a binary with the emulator.






        share|improve this answer












        The problem is that the emulator is emulating a LOT more than just the CPU. So in addition to transpiling the 6502 code to Intel code (and don't think that's simple - making the timing come out right would be a fascinating problem), you also need to provide code (analogous to the standard libraries that any program uses) that provide an emulated I/O environment that the 6502 code can manipulate.



        It'd be much easier to just bundle the emulator and program into one binary and ship that. This is what Ian Bogost did with A Slow Year - the 6502 binary is just wrapped up into a binary with the emulator.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 1 hour ago









        Michael Kohne

        46616




        46616







        • 1




          The question is also based upon a fundamental misunderstanding that the code in question exists in "lines" that can be compiled.
          – JdeBP
          1 hour ago










        • Okay, In what way?
          – Jack Kasbrack
          56 mins ago












        • 1




          The question is also based upon a fundamental misunderstanding that the code in question exists in "lines" that can be compiled.
          – JdeBP
          1 hour ago










        • Okay, In what way?
          – Jack Kasbrack
          56 mins ago







        1




        1




        The question is also based upon a fundamental misunderstanding that the code in question exists in "lines" that can be compiled.
        – JdeBP
        1 hour ago




        The question is also based upon a fundamental misunderstanding that the code in question exists in "lines" that can be compiled.
        – JdeBP
        1 hour ago












        Okay, In what way?
        – Jack Kasbrack
        56 mins ago




        Okay, In what way?
        – Jack Kasbrack
        56 mins ago










        up vote
        3
        down vote













        Whether or not it's possible isn't the only defining factor that goes into development. Keep in mind that the quality of an emulator is very much connected to it's ability to create TAS, Savestate, use RAMWatch, and so on, all of which would not be possible if the ROM was converted to a .EXE file. With this in mind, developers haven't been interested in creating such a thing, which is the very reason why it isn't "possible" with the knowledge that the community is likely to have.






        share|improve this answer








        New contributor




        DrMeta is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.





















          up vote
          3
          down vote













          Whether or not it's possible isn't the only defining factor that goes into development. Keep in mind that the quality of an emulator is very much connected to it's ability to create TAS, Savestate, use RAMWatch, and so on, all of which would not be possible if the ROM was converted to a .EXE file. With this in mind, developers haven't been interested in creating such a thing, which is the very reason why it isn't "possible" with the knowledge that the community is likely to have.






          share|improve this answer








          New contributor




          DrMeta is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.



















            up vote
            3
            down vote










            up vote
            3
            down vote









            Whether or not it's possible isn't the only defining factor that goes into development. Keep in mind that the quality of an emulator is very much connected to it's ability to create TAS, Savestate, use RAMWatch, and so on, all of which would not be possible if the ROM was converted to a .EXE file. With this in mind, developers haven't been interested in creating such a thing, which is the very reason why it isn't "possible" with the knowledge that the community is likely to have.






            share|improve this answer








            New contributor




            DrMeta is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.









            Whether or not it's possible isn't the only defining factor that goes into development. Keep in mind that the quality of an emulator is very much connected to it's ability to create TAS, Savestate, use RAMWatch, and so on, all of which would not be possible if the ROM was converted to a .EXE file. With this in mind, developers haven't been interested in creating such a thing, which is the very reason why it isn't "possible" with the knowledge that the community is likely to have.







            share|improve this answer








            New contributor




            DrMeta is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.









            share|improve this answer



            share|improve this answer






            New contributor




            DrMeta is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.









            answered 13 mins ago









            DrMeta

            312




            312




            New contributor




            DrMeta is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.





            New contributor





            DrMeta is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.






            DrMeta is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.




















                up vote
                1
                down vote













                Compiling the instructions of an arbitrary processor (e.g. a 6502) into code that will run on a modern PC should be pretty easy. After all, it's not far different from what's done by any just-in-time compiler for a language that's distributed as bytecode (e.g. Java, .NET, and so on) and simpler than a JIT compiler for a language that needs non-trivial parsing (e.g. Javascript). The easy way would be to use an existing code generator (e.g. LLVM or gcc) and just add a very simple front end that read the machine code and generated the appropriate intermediate instructions...



                There are three things that make this much more complex than it seems:



                • First, you'd need to emulate the hardware other than the CPU, so the graphics system, the audio system, etc. Along with this you'd need to provide a pre-translated version of any firmware that's expected to be present on your target system so that it can be linked in to the code you're compiling.


                • Second, you need to identify what parts of the ROM are actually instructions to be executed, and what parts are data (e.g. sprites, audio tracks, game level maps, etc). The data parts need to be handled differently -- ideally, translated into a more easily accessed format (especially multi-byte numbers, either integers or floating point, which could easily be in a format that the host processor doesn't natively understand).


                • Third, and possibly more interestingly, all of this may in fact be somewhat less legal than just using interpreted emulation. Many software and hardware vendors have granted permission to allow their code (either firmware or games) to be used in emulators, as long as they remain unchanged (e.g. I know that this is the situation with the ROMs for the Sinclair ZX Spectrum, which have been released under terms like these by their current copyright holder, Amstrad PLC). But recompiling it for a new system does change it. Even when copyright permission hasn't been granted, there are a variety of exceptions to copyright that allow minimal copying to be performed (e.g. copying the contents of a cartridge ROM onto disk for easier access) if that's necessary to make it work -- but recompiling isn't necessary, so even where there's no explicit licence grant available it may be less legal to recompile for a new architecture than just to emulate the old one. (I'm not a lawyer, so take this with a very large pinch of salt, but I have spent a reasonable amount of time learning about copyright law, and I'm pretty confident this position)





                share
























                  up vote
                  1
                  down vote













                  Compiling the instructions of an arbitrary processor (e.g. a 6502) into code that will run on a modern PC should be pretty easy. After all, it's not far different from what's done by any just-in-time compiler for a language that's distributed as bytecode (e.g. Java, .NET, and so on) and simpler than a JIT compiler for a language that needs non-trivial parsing (e.g. Javascript). The easy way would be to use an existing code generator (e.g. LLVM or gcc) and just add a very simple front end that read the machine code and generated the appropriate intermediate instructions...



                  There are three things that make this much more complex than it seems:



                  • First, you'd need to emulate the hardware other than the CPU, so the graphics system, the audio system, etc. Along with this you'd need to provide a pre-translated version of any firmware that's expected to be present on your target system so that it can be linked in to the code you're compiling.


                  • Second, you need to identify what parts of the ROM are actually instructions to be executed, and what parts are data (e.g. sprites, audio tracks, game level maps, etc). The data parts need to be handled differently -- ideally, translated into a more easily accessed format (especially multi-byte numbers, either integers or floating point, which could easily be in a format that the host processor doesn't natively understand).


                  • Third, and possibly more interestingly, all of this may in fact be somewhat less legal than just using interpreted emulation. Many software and hardware vendors have granted permission to allow their code (either firmware or games) to be used in emulators, as long as they remain unchanged (e.g. I know that this is the situation with the ROMs for the Sinclair ZX Spectrum, which have been released under terms like these by their current copyright holder, Amstrad PLC). But recompiling it for a new system does change it. Even when copyright permission hasn't been granted, there are a variety of exceptions to copyright that allow minimal copying to be performed (e.g. copying the contents of a cartridge ROM onto disk for easier access) if that's necessary to make it work -- but recompiling isn't necessary, so even where there's no explicit licence grant available it may be less legal to recompile for a new architecture than just to emulate the old one. (I'm not a lawyer, so take this with a very large pinch of salt, but I have spent a reasonable amount of time learning about copyright law, and I'm pretty confident this position)





                  share






















                    up vote
                    1
                    down vote










                    up vote
                    1
                    down vote









                    Compiling the instructions of an arbitrary processor (e.g. a 6502) into code that will run on a modern PC should be pretty easy. After all, it's not far different from what's done by any just-in-time compiler for a language that's distributed as bytecode (e.g. Java, .NET, and so on) and simpler than a JIT compiler for a language that needs non-trivial parsing (e.g. Javascript). The easy way would be to use an existing code generator (e.g. LLVM or gcc) and just add a very simple front end that read the machine code and generated the appropriate intermediate instructions...



                    There are three things that make this much more complex than it seems:



                    • First, you'd need to emulate the hardware other than the CPU, so the graphics system, the audio system, etc. Along with this you'd need to provide a pre-translated version of any firmware that's expected to be present on your target system so that it can be linked in to the code you're compiling.


                    • Second, you need to identify what parts of the ROM are actually instructions to be executed, and what parts are data (e.g. sprites, audio tracks, game level maps, etc). The data parts need to be handled differently -- ideally, translated into a more easily accessed format (especially multi-byte numbers, either integers or floating point, which could easily be in a format that the host processor doesn't natively understand).


                    • Third, and possibly more interestingly, all of this may in fact be somewhat less legal than just using interpreted emulation. Many software and hardware vendors have granted permission to allow their code (either firmware or games) to be used in emulators, as long as they remain unchanged (e.g. I know that this is the situation with the ROMs for the Sinclair ZX Spectrum, which have been released under terms like these by their current copyright holder, Amstrad PLC). But recompiling it for a new system does change it. Even when copyright permission hasn't been granted, there are a variety of exceptions to copyright that allow minimal copying to be performed (e.g. copying the contents of a cartridge ROM onto disk for easier access) if that's necessary to make it work -- but recompiling isn't necessary, so even where there's no explicit licence grant available it may be less legal to recompile for a new architecture than just to emulate the old one. (I'm not a lawyer, so take this with a very large pinch of salt, but I have spent a reasonable amount of time learning about copyright law, and I'm pretty confident this position)





                    share












                    Compiling the instructions of an arbitrary processor (e.g. a 6502) into code that will run on a modern PC should be pretty easy. After all, it's not far different from what's done by any just-in-time compiler for a language that's distributed as bytecode (e.g. Java, .NET, and so on) and simpler than a JIT compiler for a language that needs non-trivial parsing (e.g. Javascript). The easy way would be to use an existing code generator (e.g. LLVM or gcc) and just add a very simple front end that read the machine code and generated the appropriate intermediate instructions...



                    There are three things that make this much more complex than it seems:



                    • First, you'd need to emulate the hardware other than the CPU, so the graphics system, the audio system, etc. Along with this you'd need to provide a pre-translated version of any firmware that's expected to be present on your target system so that it can be linked in to the code you're compiling.


                    • Second, you need to identify what parts of the ROM are actually instructions to be executed, and what parts are data (e.g. sprites, audio tracks, game level maps, etc). The data parts need to be handled differently -- ideally, translated into a more easily accessed format (especially multi-byte numbers, either integers or floating point, which could easily be in a format that the host processor doesn't natively understand).


                    • Third, and possibly more interestingly, all of this may in fact be somewhat less legal than just using interpreted emulation. Many software and hardware vendors have granted permission to allow their code (either firmware or games) to be used in emulators, as long as they remain unchanged (e.g. I know that this is the situation with the ROMs for the Sinclair ZX Spectrum, which have been released under terms like these by their current copyright holder, Amstrad PLC). But recompiling it for a new system does change it. Even when copyright permission hasn't been granted, there are a variety of exceptions to copyright that allow minimal copying to be performed (e.g. copying the contents of a cartridge ROM onto disk for easier access) if that's necessary to make it work -- but recompiling isn't necessary, so even where there's no explicit licence grant available it may be less legal to recompile for a new architecture than just to emulate the old one. (I'm not a lawyer, so take this with a very large pinch of salt, but I have spent a reasonable amount of time learning about copyright law, and I'm pretty confident this position)






                    share











                    share


                    share










                    answered 9 mins ago









                    Jules

                    8,29222244




                    8,29222244




















                        up vote
                        0
                        down vote













                        Not quite a complete answer; however, many emulators of the consoles like playstation and alike do in some sense the same you are asking about.



                        Instead of precisely executing the code and precisely emulating the hardware, some typical code pieces (mostly connected with 3D transformations and rendering) are recognized as a whole and the end result is just inserted in the machine state or rendered using host 3D capabilities. The reason in doing so is probably lack of detailed hardware information and the speed of host CPU being not enough to emulate everything precilesy.





                        share
























                          up vote
                          0
                          down vote













                          Not quite a complete answer; however, many emulators of the consoles like playstation and alike do in some sense the same you are asking about.



                          Instead of precisely executing the code and precisely emulating the hardware, some typical code pieces (mostly connected with 3D transformations and rendering) are recognized as a whole and the end result is just inserted in the machine state or rendered using host 3D capabilities. The reason in doing so is probably lack of detailed hardware information and the speed of host CPU being not enough to emulate everything precilesy.





                          share






















                            up vote
                            0
                            down vote










                            up vote
                            0
                            down vote









                            Not quite a complete answer; however, many emulators of the consoles like playstation and alike do in some sense the same you are asking about.



                            Instead of precisely executing the code and precisely emulating the hardware, some typical code pieces (mostly connected with 3D transformations and rendering) are recognized as a whole and the end result is just inserted in the machine state or rendered using host 3D capabilities. The reason in doing so is probably lack of detailed hardware information and the speed of host CPU being not enough to emulate everything precilesy.





                            share












                            Not quite a complete answer; however, many emulators of the consoles like playstation and alike do in some sense the same you are asking about.



                            Instead of precisely executing the code and precisely emulating the hardware, some typical code pieces (mostly connected with 3D transformations and rendering) are recognized as a whole and the end result is just inserted in the machine state or rendered using host 3D capabilities. The reason in doing so is probably lack of detailed hardware information and the speed of host CPU being not enough to emulate everything precilesy.






                            share











                            share


                            share










                            answered 49 secs ago









                            lvd

                            2,474417




                            2,474417



























                                 

                                draft saved


                                draft discarded















































                                 


                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function ()
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fretrocomputing.stackexchange.com%2fquestions%2f8121%2fis-it-possible-to-make-a-rom-converter%23new-answer', 'question_page');

                                );

                                Post as a guest













































































                                Comments

                                Popular posts from this blog

                                What does second last employer means? [closed]

                                Installing NextGIS Connect into QGIS 3?

                                One-line joke