It is currently Fri Oct 20, 2017 3:46 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 13 posts ] 
Author Message
PostPosted: Tue Mar 25, 2014 8:26 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19104
Location: NE Indiana, USA (NTSC)
There's a principle in software engineering: Don't Repeat Yourself. By this, Hunt and Thomas mean "Every piece of knowledge must have a single, unambiguous, authoritative representation within a system." But unfortunately, technical and political obstacles inherent in certain platforms don't always make this easy.

Some time ago, I wrote a proof-of-concept implementation of 6502 assembly language as ca65 macros that output .byte statements. I intended for this to lead to an assembler that emits SPC700 opcodes, so that I can share music sequence interpretation code between NES and Super NES versions of a music engine. And blargg delivered, first by making a Sony-syntax assembler as a macro pack, then by adding a layer of 65C02-to-Sony preprocessor macros on top of that.

Today I noticed that Leushenko of Programming Puzzles & Code Golf Stack Exchange implemented something along the same lines: an x86-to-C assembler as a set of C preprocessor macros. In theory, this would help with porting old PC games that use assembly language subroutines to modern ARM-based platforms. And doing something similar for 6502 would allow sharing game logic code between NES and PC versions of a game.

Very polyglot. Such portability. Wow.


Top
 Profile  
 
PostPosted: Tue Mar 25, 2014 9:31 pm 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 3943
Sounds like static recompilation all over again, but with C code instead of ASM output.
I was reading about static recompilation once, and the thing that stood out the most was the optimization of deferring flag calculation until you actually need its value.

_________________
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!


Top
 Profile  
 
PostPosted: Wed Mar 26, 2014 10:20 am 
Offline

Joined: Tue May 26, 2009 5:39 am
Posts: 19
tepples wrote:
And doing something similar for 6502 would allow sharing game logic code between NES and PC versions of a game.

this remind me of Microchess C Emulation
Quote:
Download the Microchess C Emulation, which includes Microchess for the Kim-1 with 6502 to C macros and an exe file for playing Microchess on a PC as created by Bill Forster.


Top
 Profile  
 
PostPosted: Wed Mar 26, 2014 10:54 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7231
Location: Chexbres, VD, Switzerland
While it's usually always possible to translate source code from a language to another automatically, the result will usually suck and be unusable, just like machine translation of a human language.

I don't really get the point, if you want to get high quality source code that is understandable and maintenable to some extent you'll have to translate manually anyways. And if you don't want this, why translate in the 1st place ? It's probably much easier / makes more sense to interpret the 1st language in a source code written in the 2nd language.

PS : What I said doesn't apply to high level langauge -> assembly/binary translation which is compilation, but applies to all other kind of translations.


Top
 Profile  
 
PostPosted: Wed Mar 26, 2014 11:06 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19104
Location: NE Indiana, USA (NTSC)
Manual translation violates Don't Repeat Yourself. It allows bugs to exist in the logic of one version but not in another. And there's no way to efficiently propagate changes from the original to a manual translation.

Are you claiming that you would prefer to embed a 6502 interpreter in a PC version, or an interpreter for some other language in both the PC version and the NES version? The overhead of an interpreter has a runtime speed or electric power cost (which may or may not be negligible).


Top
 Profile  
 
PostPosted: Wed Mar 26, 2014 11:15 am 
Offline
User avatar

Joined: Sun Jan 02, 2011 11:50 am
Posts: 522
Translation of assembly to C could be done manually without potentially changing any of the logic or introducing bugs if the C compiler for the target CPU can be controlled in such a way to produce an identical binary file(s).


Top
 Profile  
 
PostPosted: Wed Mar 26, 2014 11:47 am 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6286
Location: Seattle
I'm kind of amused at the idea of throwing a C compiler—which theoretically has a code optimizer that's all about fixing code to be fast instead of understandable—and repurposing it to do static recompilation.

I'm a little concerned that older ISAs with their paucity of first-class registers, and with having to emulate smaller register sizes, won't translate well; theoretically this is something currently fixed with hardware-level register renaming instead of a higher-level software solution.

The Microchess example is a good data point for this purpose, though: e.g. the STRATGY function was 55 lines of 6502 and approximately 110 bytes, becomes 185 lines of x86_64 and approximately 680 bytes.


Top
 Profile  
 
PostPosted: Wed Mar 26, 2014 2:02 pm 
Offline
User avatar

Joined: Mon Feb 07, 2011 12:46 pm
Posts: 920
tepples wrote:
Are you claiming that you would prefer to embed a 6502 interpreter in a PC version, or an interpreter for some other language in both the PC version and the NES version?
I would prefer to just make the PC version include an emulator (and possibly enhancements too, dealing with graphics, input, music, and save files), and then the ROM image can be transferred to run on any other computers with an emulator, and on EEPROM cartridges.

_________________
.


Top
 Profile  
 
PostPosted: Wed Mar 26, 2014 2:34 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7231
Location: Chexbres, VD, Switzerland
Quote:
Manual translation violates Don't Repeat Yourself. It allows bugs to exist the logic of one version but not in another.

What about tossing the version in the older language ?

When I translated GBAMusRiper from Java to C++ as I've realized a year after I made the wrong choice of a language, I tossed the old Java version. I was able to make the code more elegant and add some functionalities while translating, too.

Quote:
Are you claiming that you would prefer to embed a 6502 interpreter in a PC version, or an interpreter for some other language in both the PC version and the NES version? The overhead of an interpreter has a runtime speed or electric power cost (which may or may not be negligible).

Wow it depends so much on the application you can't have general rules about this kind of stuff.

I'd say the only general rule when it comes to computer science is that there is no general rule ;)
I hate people saying stuff like "you should NEVER use break or continue" or "you should never program in assembly" or whatever. It just depends on what you want to do and what are your goals. Just know what you're doing and think like a grow up man with common sense, instead of blindly following rules other random people made (if those people are famous, it's even one more reason NOT to follow them blindly).

If you're targeting two platforms with different CPUs, and want to maintain the code on both at the same time, assembly is probably a terrible choice. But if you already coded in 6502 assembly and refuse to translate to something else, then an interpreter is definitely the best solution.
The resulting code probably won't be significantly less per formant that a horrible decompilation and recompiled zombie C code, but writing an interpreter is much more elegant.


Top
 Profile  
 
PostPosted: Wed Mar 26, 2014 3:40 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5718
Location: Canada
For porting an old assembly program to a new architecture that outclasses it, this is a fine solution. It's probably about the same complexity as an emulator to write, but by doing the transcode statically you get to trade code size for a more efficient emulation, especially if you've got a good optimizing compiler to feed it into.

I don't think I'd want to use this to cross develop NES + PC though. I am currently working on an NES game by writing it in C++ for PC with the NES limitations in mind, then manually porting the code to NES assembly once I have finished iterating on the C++ version. I find it insanely easier to make iterations and changes to C++ code vs assembly, so I think there would be a lot lost by doing primary development in assembly.


Top
 Profile  
 
PostPosted: Wed Mar 26, 2014 5:48 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19104
Location: NE Indiana, USA (NTSC)
rainwarrior wrote:
I am currently working on an NES game by writing it in C++ for PC with the NES limitations in mind

And I've done so in Python, both for subroutines and for main. Mr. Podunkian did it for STREEMERZ, with thefox completing the port.

Quote:
then manually porting the code to NES assembly once I have finished iterating on the C++ version.

The problem with this sort of waterfall model comes when you think you've "finished iterating" but you think of changes to make after you've made progress on the port. Unless you abandon the original C++ version entirely, you have to maintain them in parallel.


Top
 Profile  
 
PostPosted: Thu Mar 27, 2014 12:38 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7231
Location: Chexbres, VD, Switzerland
Quote:
For porting an old assembly program to a new architecture that outclasses it, this is a fine solution. It's probably about the same complexity as an emulator to write, but by doing the transcode statically you get to trade code size for a more efficient emulation, especially if you've got a good optimizing compiler to feed it into.

Even the best optimizing compilers are designed to work with "normal" code. Decompiled assembly code is going to look like a huge mess (with statements like a = , x =, y = and so on for emulating the corresponding 6502 instructions), and the optimizing compiler isn't likely to find the corresponding assembly code again.


Top
 Profile  
 
PostPosted: Thu Mar 27, 2014 6:12 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5718
Location: Canada
I mean that an optimizer run on what is essentially an "unrolled" emulation of a program should perform significantly better than the equivalent emulator. Whether or not the compiler can do optimizations has nothing to do with "normal" code, machine generated code can optimize well or poorly, and the generator can be tuned to create well-optimizing code if you know enough about the compiler it's going to feed.

I actually maintained a code generator in this way on my last job; it was an interesting experience. Occasionally you do get unlucky and your first approach generates worst-case code for the compiler, but you can fix this if you're paying attention. A lot of the time you get to watch large chunks of generated code just evaporate in the optimization step.

There is not really any hope of recovering the original assembly via a normal compiler, but why would you be compiling back to 6502? My statement about efficiency was not a comparison to well crafted assembly.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 13 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: 93143 and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group