Skip to main content
gamedev.net
🔒 Locked

Assembly question

Started by sakky Aug 15, 2006 at 4:09 AM 4 replies 1.2k views
Original Post
sakky
sakky
I'm learning assembly and there are a few things I'm worried about. I want to translate machine language 6502 machine language to x86 and I'm not sure if I can get away with it for reasons I will explain. LDA (Load Accumulator) is a 6502 instruction that can be translated to "mov al, $data" and I would like to directly translate a lot of other instructions in this manner. Such as the LDX, LDA, etc.. Instructions I'm worried about are stack functions or flag functions. Do I have to use a ROMs memory space to store the stack or can I get away with using the x86's? x86's meaning MY processor or the host. A good reason why I'm so worried is when the simulator/emulator for the 6502's routines are finished and general the application program stuff like Windows message loop and what not. If I use the host processor for a stack and processor state (i.e. pushes and pops), will I end back up were I should if where I left off? Meaning, what if some code pushes or pops something off the stack that I put there? That is one reason why I'm worried about using the host processor because I don't want other code messing up the emulation. Second, I'm worried if I should write the stack to the ROM's memory space or not. I wouldn't have to if I was using the host. This *could* speed. But certain tings I know I will have to write to the ROM's memory. Things like read/write routines that are specific, like memory addressing. But not if I use the host for most of the other stuff, right? For example:

LDA #$10
STA $2020  // would have to make a write here!

LDA #$20
PHA        // wouldn't have to write, use host's stack (i.e. "push al" for x86)

See what I mean. I only see a problem when I go back to PLA (Pull accumulator) and I get a wrong value because something else pushed something there! But so far, I only see that I would have to write to ROM memory space when I cross an instruction that does so. Other wise, I belive I can get away with completely using the host. Only problems I see arethe stack and maybe the X,Y registers. I think BX, BP, SI or one of those sorts, may work. Please help with some advice. Thanks in advance :D
Take back the internet with the most awsome browser around, FireFox
ApochPiQ
ApochPiQ
Mapping one machine's dialect of assembler onto another's is not trivial. While it is theoretically possible to come up with a "search-and-replace" mapping that will convert one instruction set to another, in practice it's a royal pain.

Anyways, I'm not really clear on what it is you're wanting to do. Generally, if you want to code X instruction set, you have some hardware that speaks X, or you write an emulator that fully speaks X but actually runs on hardware Y.

In your case, it sounds like you have three basic options: get a processor that runs 6502, translate by hand to x86, or find/create an emulator and run the 6502 stuff on a virtual machine on top of your x86. I'm really not sure which to recommend, though, because as I said I'm not sure what exactly you're looking to accomplish.


(Oh, one other thing - you don't write to ROMs. They're called Read Only Memory for a reason. Stack and freestore is the responsibility of the host machine, either physical or virtual.)
t0Xic
t0Xic
Can someone tell him that different threads don't use the same stack ...


t0}{!c
robotichrist
robotichrist
Well, this is in general non-trivial. You could use a separate register, say ESI to do store the address space for 6502, then perform indirect addressing for reads and stores, eg:

sta $2002 --> mov ESI[0x2002], EAX

However, this is not always such a good idea. Looking at those memory address, I suspect you are trying to build an NES emulator. The NES integrates the ram, cartridge mapper and all video hardware on the same bus. It is probably better to just have a single function call for write/read which handles all memory operations.

There are other problems as well. Jumps won't work quite the same, since the instruction lengths on the 6502 and x86 do not match up at all. You would have to either trace the function, then recompile it, or store a 256k 'jump buffer' to translate each instruction into a specific address.

Also, most NES games swap out the entire program ROM using mappers. This will force you to recompile and recompute the entire jump buffer every time a bank switches. Some games, such as Kirby's Adventure, even use dynamic self-modifying code on the 0-page.

In the end, I would advise you to just write a normal emulator and avoid machine code translation. On an NES, it probably won't even have a substantial performance advantage. Once you get everything working in a regular emulator, then it will be much easier to do advanced modifications and performance hacks.
sakky
sakky
Quote:
Original post by t0Xic
Can someone tell him that different threads don't use the same stack ...


t0}{!c


A.....doe! I seam to forgot that fact. Oops!

What I'm trying to do-> Yes, I'm trying to write an emulator. For the NES + others. From what I've read 65(02/ C02 / C816) all use the same insruction set, just added instruction in the processors. So in the long run, coding the C816 would probebly give you the emulator for the other two. Or aleast I think, because only a few of the instructions use 32-Bit addressing more the C816 uses. or the addressing modes are designated 16/32 via 02/C02 vs C816.

Any ways, I wanted to translate the instruction set from those three in x86. I see that they are a lot like x86 so it would be easier to tranlate them in such ways. The ASM emulators I've seen use this sort of style. The instructions are just macros like the addressing modes are. The only *real* difference is that I would be using the x86 ASM in place of 65*.02 ASM.

What I was worried about was the stack getting all messed up. But since I don't haveto. I just need to write macros for the addressing modes which arn't that hard to do. Then use the x86's registers inplace of the 65*.02's registers and directly translate the instructions. Some of the branch/jump and int functions may be a pain though.

I've got an so/so emulator in C already that I've wrote. But I want on in ASM. Also, I haven't been able to test the C emulator yet and it also *only* supports the 6502's addressing mores & not the 65C02's even though I have C02 instructions implemented. I may have to reqrite a few of them because the bit operations Hi vs. lo endy and other special bit & flag operations may be a little inaccurate.

I thought it would be a learning experience + a little easier and a lot faster is I rewrote it in ASM. All the other emulators I see use the same array of functions & int for the insrtuction set & addressing mores + a cyclic table.

By the way, I'm using MASM(v7?) that comes with Visual C++.NET + Service Pack & Platform SDK Update.
Take back the internet with the most awsome browser around, FireFox
sakky
sakky
PS. I know about mappers. Thanks for the help guys!!!
Take back the internet with the most awsome browser around, FireFox

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.