6800 assembly to 65xx?

Programming the 6502 microprocessor and its relatives in assembly and other languages.
Post Reply
Meterman58761
Posts: 19
Joined: 05 Jun 2021

6800 assembly to 65xx?

Post by Meterman58761 »

So I've got a project that used a variant of the 6800 that was developed for automotive applications (pinout similar to the 6800, but had the 6801 instruction set).

The CPU I was using was a used part and apparently is dead in the water... I did manage to find one remaining source but they want over $50 apiece.

So, I'm looking at various approaches, and one is re-coding to run on the 65816.

Is there any kind of reference how to implement various 6800-class instructions on the 65xx CPUs? I am MUCH more familiar with the 65xx CPUs anyway as I once had a C64.

The instructions I'm interested in at the moment are TST, BGT, BLE, BLT.

Since TST checks for the Z and N flags, would a CMP #$00 do the same thing?
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: 6800 assembly to 65xx?

Post by barrym95838 »

Hi, Meterman!

Translating 68xx to 65xx is a nice way to spend lots of your time. I did so for the VTL-2 interpreter, and found that the missing B accumulator and the narrow X and S registers required some careful treatment. This was solved by bringing the 65xx's excellent indirect addressing modes into play, but definitely took considerable thought and effort to do it efficiently. A simple example would be to keep the 68xx X register in the 65xx zp and use (zp,X) with x = 0 or (zp),Y with Y = offset, but that's definitely over-simplifying. If you go with the 65c816, you can ease some of the translation burden by going to native mode and selecting 16-bit index registers (and applying XBA as appropriate).

The best way to implement the test instruction depends somewhat on what you're testing. For TSTA you can use ORA #0. For TST memory you can substitute LDY memory. CMP #0 will TSTA, but will also set the carry flag.

BGT, BLE and BLT can all be synthesized with two (or worst case three?) 65xx branch instructions. It's important to remember that the 65xx uses the idea that a borrow from a subtract or a compare clears the carry flag, which can twist you up from time-to-time. That, and the 65xx is little-endian.

Code density should slightly favor the 68xx for typical activities, and cycle counts should slightly favor the 65xx ... if you're doing it right :-)

Good luck, and let us know how things go.
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: 6800 assembly to 65xx?

Post by BigDumbDinosaur »

Meterman58761 wrote:
So I've got a project that used a variant of the 6800 that was developed for automotive applications (pinout similar to the 6800, but had the 6801 instruction set).

The CPU I was using was a used part and apparently is dead in the water... I did manage to find one remaining source but they want over $50 apiece.

So, I'm looking at various approaches, and one is re-coding to run on the 65816.

Is there any kind of reference how to implement various 6800-class instructions on the 65xx CPUs? I am MUCH more familiar with the 65xx CPUs anyway as I once had a C64.

The instructions I'm interested in at the moment are TST, BGT, BLE, BLT.

Since TST checks for the Z and N flags, would a CMP #$00 do the same thing?

May I suggest you download a copy of Lance Leventhal's 6502 ASSEMBLY LANGUAGE PROGRAMMING and refer to page 3-105? Leventhal does a pretty good job of summarizing the differences between the 6800 and 6502 assembly languages. About half of each processor's instruction set is in common with the other, but there are some significant differences in the other half.

As Barry noted, TST can be synthesized in several ways. If the value being tested is already loaded into the accumulator, ORA #0 will set/clear the Z flag in the status register (SR), as will AND #%11111111—neither instruction will change the value in .A. If the value is in memory, the act of loading it into any register will do the same thing.

The branch instructions you mentioned can be implemented with a sequence of branch instructions in 6502 assembly language. The names are different but the principle is the same.

Using the 65C816 should make it easier for you, especially since, as Barry noted, you can use 16-bit index registers, plus the 816 has A- and B-accumulators and a 16-bit stack pointer.

Please keep us apprised on how your project is going. Incidentally, the hardware adaptation the 816 to your project should keep you busy as well. :D
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: 6800 assembly to 65xx?

Post by BigEd »

Welcome, Meterman!

Once you have a bit of a grounding in the instruction sets, a good old-fashioned single page reference card might be a good way to compare and constrast.

It took me a while to find them, for some reason, but here are the one page programmers guides from Jonathan Bowen of the Oxford University Computing Laboratory, and specifically (Previous thread: Instant Reference Card)
BillG
Posts: 710
Joined: 12 Mar 2020
Location: North Tejas

Re: 6800 assembly to 65xx?

Post by BillG »

Meterman58761 wrote:
The instructions I'm interested in at the moment are TST, BGT, BLE, BLT.
If you are testing a memory location, take a close look at the 6502 BIT instruction. Like the 6800 BIT, it ANDs register A with the memory location to determine the Z flag. But it also determines the N and V flags based solely on the upper two bits of the memory location (unaffected by the contents of register A) making for a very efficient way to implement a couple of flags within a memory location. I wish the 680x had something similar.

You can somewhat make up for the loss of accumulator B by moving values into registers X or Y. There are a few times when the two not-quite-accumulators X and Y are better than the second full-accumulator B.

BGT, BLE and BLT are for signed comparisons. You cannot use CMP for the test because it does not affect the V flag. You must use the combination of SEC followed by SBC.

Speaking of, the 6502 does not have add without carry or subtract without borrow; be careful to do CLC before ADC and SEC before SBC if you do not want a carry or borrow involved.

If your assembler provides BLO as an alias for BCC and BHS for BCS, use them where appropriate to make your code more obvious. For example,

Code: Select all

    cmp   #'0'
    blo   NotNumeric
instead of

Code: Select all

    cmp   #'0'
    bcc   NotNumeric
If your assembler does not, create a macro to do that if your assembler supports them.

Finally, it is easy to be spoiled by the variety of conditional branches on the 680x. Even the 68000 comes up short.

If your 680x code does this:

Code: Select all

    cmpa   #'9'
    bhi   NotNumeric
do this on the 6502:

Code: Select all

    cmp   #'9'+1
    bhs   NotNumeric
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: 6800 assembly to 65xx?

Post by BigDumbDinosaur »

BigEd wrote:
It took me a while to find them, for some reason, but here are the one page programmers guides from Jonathan Bowen of the Oxford University Computing Laboratory, and specifically
6502 MICROPROCESSOR Instruction Set Summary
6800 MICROPROCESSOR Instruction Set Summary

That 6800 reference card is nice. Too bad it wasn't available when I was introduced to the 6800 in the late 1970s.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
Meterman58761
Posts: 19
Joined: 05 Jun 2021

Re: 6800 assembly to 65xx?

Post by Meterman58761 »

Thanks all for the welcome and the encouragement on the challenge ahead of me.

I already know that I have a BIG task ahead of me. The other option currently on my plate is translating the 68xx into C++ instead…

As for addressing modes, fortunately the indexed mode don’t come into play that much, as most is used as a hard-coded offset (that can be substituted for the destination location directly) or is so written that rearranging the base and index into 65xx style is almost trivial.

The bulk of the code uses zero page (locations $00-$0F and $80-$E2), with some absolute addressing ($0C00-$0C3F and $0CF8-$0CFF).

The three branch instructions I mentioned I am fairly certain are the only non-65xx branches used in my code (the code also makes use of BPL / BMI, BEQ / BNE, BCC / BCS - those I’m not worried about, and it seems the 65816 adds the BRA instruction which I also have in the code).

The BIG headache, though, is going to be math - the 16-bit D register actually sees a fair bit of usage. ...there is even a a single subroutine that contains the MUL operand.

I can provide a breakdown of the specific opcodes and modes used, OR if it's okay with you all, I can attach a text dump of the interrupt routine (If I can master this routine, the rest should fall in fairly easily) so you can see how the code is.

Also, if it helps, I can lay out the memory map that the code uses (it’s kinda weird because partial address decoding).

I will definitely look for the book suggested later today.
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: 6800 assembly to 65xx?

Post by BigDumbDinosaur »

I should mention that Lance Leventhal also wrote 6800 ASSEMBLY LANGUAGE PROGRAMMING, which is in the same style as the 6502 book. He cranked out books like that for other MPUs of the time as well. I had a copy of his 6800 book years ago, but gave it away when general interest in the 6800 stated fading away.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
Meterman58761
Posts: 19
Joined: 05 Jun 2021

Re: 6800 assembly to 65xx?

Post by Meterman58761 »

Here's the interrupt code I mentioned.
Attachments
fct int.txt
(5.65 KiB) Downloaded 133 times
Post Reply