05 January 2015, 22:00 | #1 |
Zone Friend
Join Date: Apr 2006
Location: Gothenburg/Sweden
Age: 48
Posts: 345
|
Converting 6502 to 680x0 (calling all 6502/680x0 experts)
I've been playing with the idea of converting 6502 code to 680x0 code (a little bit inspired by the Atari-ports found elsewhere in this forum).
Many 6502 instructions can be converted to a eqvivalent 680x0 instruction, however a few is causing me minor headaches. Instructions such as: STA ($44,X) or STA ($44),Y for example. Any gurus here that knows any way of converting this with (preferable) as little code as possible in 68k? 68020+ code allowed. |
06 January 2015, 00:02 | #2 |
Glastonbridge Software
Join Date: Jan 2012
Location: Edinburgh/Scotland
Posts: 2,243
|
I've never worked with the 6502 but 68020 has such a "memory-indirect" addressing modes. syntax is:
move.b D0,([bd, An], Xn.SIZE * SCALE, od) or move.b D0,([bd, An, Xn.SIZE * SCALE], od) (assuming you keep your accumulator in D0) where "bd" is "Base displacement" and is added to the address register before indirection, and "od" is "Outer displacement" and is added to the result of the first fetch. These should do what you want, but the index register "Xn" is word or longword whereas the 6502 only uses a byte index, i gather. So maybe you would need to move.b the index register to some other register with a clear upper byte first. |
06 January 2015, 11:04 | #3 |
Registered User
Join Date: May 2013
Location: Grimstad / Norway
Posts: 854
|
A few pre-requisites (same as I used in AXF-64 - IIRC):
a5 = 0 d7 = 64K aligned 6502 memory d6 = d7 A = d0 ; in $000000XX format X = d1 ; same move.w #$44,d7 add.w d1,d7 move.w (a5,d7.l),d6 ; this is 020+ - I used stack shufling for this rol.w #8,d6 ; and this on 68000 move.b d0,(a5,d6.l) This can be done smaller and better if you go 020+ and if you can base yourself on a source approach. Like using 32bit offsets. A 64K aligned memory area still makes your life easier. Then you can operate on the lower 16 bits of data registers while you keep the upper 16 pointing to a valid address range. Second try: a4 = 64K aligned memory move.w $44(a4,d1.l), d7 ; 50% chance of unaligned rol.w #8,d7 move.b d0,(a5,d7.l) (Option: d1 has 64K aligned address in upper word and instead use move.w $44(a5,d1.l),d7) The other option is to point an address register in the middle of a 64K aligned block and have the positive and negative offsets take you to the whole 64K and use .w size for the data registers, but for my emulation purpose I ran out of registers IIRC and so just found it neater to do all calculations in the data register and use them as direct pointers with a dummy 0 filled address register. None of this handles flags. You want to do that obviously. If you are making a source->source converter be prepared for rather much code spewing out. OTOH hand, with a source base you can add in a static/source optimizer that sees that you generate values (flags) that are never read and as such can be dropped. You might also want to have a hint system in the original code where you can turn on and off status flag handling. How far do you want to go, and how tightly are you willing to tie it to a memory/register model to cut down source or binary size? Third try: This time also handle zeropage wrapping. I hope I am remembering the idiosyncrasies of the 6502 right... move.w #$44,d7 ; or a dedicated zeropage d5 then it would be "move.b #$44,d5" - change the lines below to use d5 add.b d1,d7 move.w (a5,d7.l),d6 ; 020+ add.b #1,d7 move.b (a5,d7.l),d6 rol.w #8,d6 move.b d0,(a5,d6.l) Now, with source - and assuming no self-modifying code - you can know that a wraparound does not happen and so add in a hint that this does not have to be handled. Good luck, and do come back and let us know how it is working out! Last edited by NorthWay; 06 January 2015 at 23:47. Reason: Forgot a ROL |
06 January 2015, 20:18 | #4 |
Zone Friend
Join Date: Apr 2006
Location: Gothenburg/Sweden
Age: 48
Posts: 345
|
Thanks for your feedback.
It's a bit annoying that there's some much "overhead" to translate these instructions to a "modern" (compared to the 6502) 680x0 CPU. I wonder if there's another way of doing it, without manually porting the code line by line (which would be a very difficult task). |
06 January 2015, 21:00 | #5 |
Glastonbridge Software
Join Date: Jan 2012
Location: Edinburgh/Scotland
Posts: 2,243
|
are you talking about porting source code, or object code? Source code would be easier.
|
06 January 2015, 21:13 | #6 |
Zone Friend
Join Date: Apr 2006
Location: Gothenburg/Sweden
Age: 48
Posts: 345
|
I've ported a Java-disassembler (NESRev by Kent Hansen) for NES-ROMs to Microsoft.NET and it's pretty good for separating code and data, so I've got the sourcecode, well, sort of. And the idea has grown over the years to being able to port something. And inspiration got even bigger when I read about the Atari-ports.
|
07 January 2015, 00:12 | #7 |
Registered User
Join Date: May 2013
Location: Grimstad / Norway
Posts: 854
|
The overhead is basically two things
-different addressing modes that have to be emulated or have a strategy for how to handle -flag status shuffling A _good_ source converter would be a full compiler that can follow the flow and logic and join together code. i.e. you would have lda #$c2 sta $a8d3 and that would be changed into move.b #$c2,$a8d3 ; well at least something based on a memory model you establish For addressing modes that map 1:1 you see that there is not necessarily so much overhead, but 6502 programmers have been sure to use all the expressiveness there is in the instruction set, like the fact that ROL does read-modify-write(nee RWW) on memory and you can use it for a fast ack/test on typical interrupt registers, or worse; execute code from the registers as that has some effect that I can't remember right now. Anyway, you'll end up with a mess that is slower clock for clock than the original, but it shouldn't take much profiling or emulator modification to find the code that takes the most time and just port it at the logic level. BTW, the Atari-ports you talked about, was that the ST ones? |
08 January 2015, 19:33 | #8 | |
Registered User
Join Date: May 2001
Location: ?
Posts: 19,658
|
Quote:
There's so much good stuff on 6502 machines that would move great to Amiga, I would love to see what you do. |
|
08 January 2015, 19:47 | #9 |
Zone Friend
Join Date: Apr 2006
Location: Gothenburg/Sweden
Age: 48
Posts: 345
|
The thread I found was about Atari-ST ports (68k), not older Atari-console ports.
|
09 January 2015, 20:52 | #10 |
Zone Friend
Join Date: Apr 2006
Location: Gothenburg/Sweden
Age: 48
Posts: 345
|
I got the 68k source for SMB (Genesis-optimized) and found out what he's been doing.
Really interesting stuff but it's obviously Genesis/Megadrive-optimized since the code has lots of move.l #1,$00000002 and similar, which obviously won't work on Amigas without killing the system itself. I'm not sure how an Amiga-optimized CPU-translated-core would look.. But it's still interesting. |
13 January 2015, 21:34 | #11 |
Registered User
Join Date: Feb 2014
Location: Germany
Posts: 6
|
|
14 January 2015, 12:30 | #12 |
Zone Friend
Join Date: Apr 2006
Location: Gothenburg/Sweden
Age: 48
Posts: 345
|
It's in the zone now. If anyone makes a working Amiga-port.. that would be awesome.
|
14 January 2015, 19:18 | #13 |
Registered User
Join Date: May 2001
Location: ?
Posts: 19,658
|
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
680x0 tester | JimDrew | support.WinUAE | 3 | 28 October 2014 20:44 |
680x0 to 68000 | Counia | Hardware mods | 1 | 01 March 2011 10:18 |
Visual 6502 in JavaScript | Charlie | Retrogaming General Discussion | 1 | 03 October 2010 13:35 |
Free : 680x0 CPU's | alexh | MarketPlace | 23 | 28 November 2009 12:29 |
6502 Asm | pmc | Coders. General | 21 | 06 November 2008 09:37 |
|
|