Orthogonal 65c02 addressing modes

Programming the 6502 microprocessor and its relatives in assembly and other languages.
Post Reply
lordsteve
Posts: 56
Joined: 22 Jan 2003
Location: Estados Unidos
Contact:

Orthogonal 65c02 addressing modes

Post by lordsteve »

Here is a scheme I am working on to extend the instructions of the 65c02 to support an orthogonal set of addressing modes. New addressing modes are introduced to round out the existing ones: " (a,y)", "(zp,y)","(zp),x". Addressing mode "r" or pc-relative has been made available to mnemonics besides the branches. And an new-to-the-65c02 sp-relative addressing mode has been added. The affected mnemonics can be seen in the second image and include the data-processing, load/store, and jmp/jsr. I contemplated adding "register X", "register Y", and other similar modes, but decided against it because of reasons.

There are not enough one-byte codes to support all the combinations of mnemonics and addressing modes. A number of ways exist with which to handle this problem, but I have opted here to use a prefix byte to extend addressing modes because it will fit with my future plans of adding 16- and 32-bit support (and more!). Few of the empty codes from the original 65c02 opcode matrix were taken here and were taken only to accommodate this prefixing scheme.

The "f3" prefix byte flips the "directness" of an addressing mode. Direct modes become indirect. The following

Code: Select all

adc $2400    ; 6d 00 24
becomes

Code: Select all

adc ($2400)    ; f3 6d 00 24
The "e3" prefix has an effect depending on the addressing mode of the base instruction.
If the original addressing mode uses an index register, X or Y, the new addressing mode uses the other index register.

Code: Select all

adc $24, x    ; 75 24
The above becomes

Code: Select all

adc $24, y    ; e3 75 24
If the original addressing mode is zp, the e3 prefix causes the addressing mode to be PC-relative (signed offset).

Code: Select all

adc $24    ; 65 24
adc $fe    ; 65 fe
The above becomes

Code: Select all

adc pc + $24    ; e3 65 24
adc pc - 2      ; e3 65 fe (signed offset relative to program counter)
Finally, "d3" acts like both "f3" and "e3": For addressing modes that have an index register, the "directness" of the addressing mode is inverted and the index register is swapped.

Code: Select all

adc $24, x    ; 75 24
The above becomes

Code: Select all

adc ($24, y)    ; d3 75 24
For addressing mode zp, "d3" changes the addressing mode to stack-relative (signed offset).

Code: Select all

adc $24    ; 65 24
adc $fe    ; 65 fe
The above becomes

Code: Select all

adc sp + $24    ; d3 65 24
adc sp - 2      ; d3 65 fe (signed offset relative to stack pointer)
Thanks for looking. Let me know if you have any helpful ideas.

The first spreadsheet is based of of Neil Parker's very helpful table here: http://www.llx.com/~nparker/a2/opcodes.html
Attachments
65x02opcodebymode.png
65x02opcodematrix.png
Last edited by lordsteve on Mon Sep 21, 2015 11:23 pm, edited 1 time in total.
Thanks for playing.
-- Lord Steve
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: Orthogonal 65c02 addressing modes

Post by Dr Jefyll »

lordsteve wrote:
Let me know if you have any helpful ideas.
Hi, lordsteve. My first suggestion is non-technical. Right now the first two (very wide) spreadsheets in your post cause the entire page to be equally wide, and that means people have to scroll horizontally back & forth just to read the text in your post. Ideally, all images (spreadsheets, photos, whatever) should be posted as attachments. I PM'd you about this and got no response, so my other suggestion is to check and see whether your email client is sending PM notifications to the Trash folder! :)

Can you elaborate on the relation between the spreadsheets you posted -- what each represents, and how they differ? And I see a color scheme is in effect, and red underlining is used; what's the significance of that? I like the concept you're working with, but some further introductory comments might be helpful.

cheers,
Jeff

ps- Another reason to post attachments, not links, is so the images get included in the 6502.org backups. That ensures they'll remain viewable in future even if the link should go dead.
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
lordsteve
Posts: 56
Joined: 22 Jan 2003
Location: Estados Unidos
Contact:

Re: Orthogonal 65c02 addressing modes

Post by lordsteve »

@Dr Jefyll
Oh, thanks for pointing that out. I removed the inline images, which were already attachments to this post.

The first, larger spreadsheet is a map of addressing modes to mnemonics. I have grouped them together (mostly) according to their available addressing modes. The black text is the original opcode for that mnemonic/addressing mode combination. In red is the new opcode allocated to the new mnemonic/addressing mode combination. The green text in the column headings is the new addressing modes I have added. The goal is to make all addressing modes available to all the mnemonics for which it makes sense to do so and to orthogonalize those addressing modes. There is no (zp),x addressing mode for the 65c02 for example, so I added it. I add prefix bytes to the original opcodes to make this happen.

The second spreadsheet with the colorful cell backgrounds is just the proposed opcode map; it is the 65c02 opcode map with the instruction I have added in red. The three opcode bytes I currently use for prefix bytes are blacked out. Green instructions are 6502 instructions. Yellow is 65c02 (non-Western-Design-Center). It is based off of Neil Parker's opcode map here: http://www.llx.com/~nparker/a2/opcodes.html.
Thanks for playing.
-- Lord Steve
theGSman
Posts: 85
Joined: 26 Jan 2015

Re: Orthogonal 65c02 addressing modes

Post by theGSman »

lordsteve wrote:
Here is a scheme I am working on to extend the instructions of the 65c02 to support an orthogonal set of addressing modes. New addressing modes are introduced to round out the existing ones: " (a,y)", "(zp,y)", ......
The question I would have to ask is "why"?

I have programmed the 6502 for many years and I don't think I have ever used the (zp,x) mode. Assuming that every byte-pair in zero page points to a memory location, a (zp,x) would only allow you to access one of 128 single bytes of memory by changing the x register.

Replacing the (zp,x) mode with (zp,x),y would be far more useful. OTOH doing away with (zp,x) altogether would make it possible to extend the addressing modes of the LDX, LDY, CPX and CPY instructions. Other useful instructions would be TXY, TYX, TSY, TYS, TSA, TAS.
White Flame
Posts: 704
Joined: 24 Jul 2012

Re: Orthogonal 65c02 addressing modes

Post by White Flame »

(beaten by the above while writing this)

One addressing mode that I always seem to desire is (zp,x),y. It comes up when there's a stack of pointers on zero page, and you want to index against that dereferenced pointer.

While this would in my mind be a one-off, in your thinking of prefix features I guess a prefix code could perform "also use the other index register" to transform (zp,x) into (zp,x),y. Non-indirect references could become LDA addr,x,y which could be useful for certain types of tables.
User avatar
GARTHWILSON
Forum Moderator
Posts: 8775
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Orthogonal 65c02 addressing modes

Post by GARTHWILSON »

theGSman wrote:
The question I would have to ask is "why"?

I have programmed the 6502 for many years and I don't think I have ever used the (zp,x) mode. Assuming that every byte-pair in zero page points to a memory location, a (zp,x) would only allow you to access one of 128 single bytes of memory by changing the x register.
(ZP,X) is very useful. We discussed it at viewtopic.php?f=2&t=2538 . Forth uses it a lot.
Quote:
Other useful instructions would be TXY, TYX, TSY, TYS, TSA, TAS.
The '816 has these because they are so useful. There's TXY, TYX, and TSC and TCS (C being the 16-bit accumulator, since the stack pointer is 16-bit), and others.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: Orthogonal 65c02 addressing modes

Post by Dr Jefyll »

theGSman wrote:
Replacing the (zp,x) mode with (zp,x),y would be far more useful.
White Flame wrote:
One addressing mode that I always seem to desire is (zp,x),y.

(zp,x),y is a mode implemented on my KK Computer, so I'm pleased to see it endorsed by others.
GARTHWILSON wrote:
(ZP,X) is very useful. [...] Forth uses it a lot.
Yes, (zp,x) mode is great for accessing a byte whose address is on the Forth data stack. And if, as commonly happens, that byte is the first of two or more in an array, then (zp,x),y is the ideal mode for accessing the rest of the array.

With KK there's a quirk arising from the use of a pre-existing CPU (65C02). Any (zp,x),y instruction must be preceded by either a special lda (zp,x) instruction or a special sta (zp,x) instruction. These access the first byte of the array and, in doing so, also copy the 16-bit effective address to a zero-page pair known as W. Having the EA copied into a known, non-indexed address in z-page means (zp),Y mode can subsequently be used, specifying W, and the overall result is (zp,x),y. KK's (zp,x),y mode is described, with a Forth code example, here. A KK overview is here.

-- Jeff
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
theGSman
Posts: 85
Joined: 26 Jan 2015

Re: Orthogonal 65c02 addressing modes

Post by theGSman »

GARTHWILSON wrote:
(ZP,X) is very useful. We discussed it at viewtopic.php?f=2&t=2538 . Forth uses it a lot.
Looking through that thread, I notice that this is true mainly for the '802/'816 processor where you can access 16 bits at once.

On a straight 6502 processor this is not the case. You can access the low-byte of a word using (zp,x) but accessing the high-byte still requires a couple of INCs first (followed by DECs if you wish to preserve the zp,x location).

@ in a 6502 would be as follows:

Code: Select all

AT   LDA (0,X)
     PHA
     INC 0,X
     BNE AT1
     INC 1,X
AT1  LDA (0,X)
     STA 1,X
     PLA
     STA 0,X
     JMP NEXT
Not much of an advantage over other forms the code might take and it means that you wouldn't be able to split the stack into a low and high section.
User avatar
GARTHWILSON
Forum Moderator
Posts: 8775
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Orthogonal 65c02 addressing modes

Post by GARTHWILSON »

The only advantage to splitting it into high and low sections is that you can eliminate an INX or a DEX here and there. It won't save any ZP memory; and if you move the data stack out of ZP (in order to get more data stack space by splitting it), the code will get bigger and slower.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
theGSman
Posts: 85
Joined: 26 Jan 2015

Re: Orthogonal 65c02 addressing modes

Post by theGSman »

GARTHWILSON wrote:
.................... (in order to get more data stack space by splitting it) ..............
Everything you say is true except the bracketed bit. Splitting doesn't change the size of the data stack. As a matter of preference I prefer a larger data stack than what would fit in a subset of zero page and had I known about the splitting trick at the time then that's what I would have done. It's not worth rewriting the code just to save a few INX/DEX instructions but it wouldn't change the size of my data stack if I did.
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: Orthogonal 65c02 addressing modes

Post by Dr Jefyll »

For my own ruminations I shrank lordsteve's diagram for a better fit on-screen. The patterns are quite apparent -- most of all, the way one column is echoed by one or more others. Example: except for the prefix, the opcodes in the (a,x) column are generally identical to opcodes in the a,x column. And the zp column is echoed both by the r column and the sr column.
orthogonal 6502.png
White Flame wrote:
I guess a prefix code could perform "also use the other index register" to transform (zp,x) into (zp,x),y.
I'm thinkin' the e3 prefix could change cases of (zp) into (zp,x),y. But either way would work.
GARTHWILSON wrote:
.................... if you move the data stack out of ZP (in order to get more data stack space by splitting it) ..............
Is this the intended context for your remark, theGSman? I think Garth means a split stack that's not in ZP could devote one entire page for the low-bytes and another entire page for the high-bytes, yielding a total of 256 sixteen-bit items. So it can double the size of the data stack. But for the sake of speed and reduced code size, the stack is usually placed in ZP, whether it's split or not. (Actually the speed issue is somewhat debatable, because zp,x and zp,y modes have a dummy cycle that makes them just as slow as abs,x and abs,y.)
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
theGSman
Posts: 85
Joined: 26 Jan 2015

Re: Orthogonal 65c02 addressing modes

Post by theGSman »

Dr Jefyll wrote:
I think Garth means a split stack that's not in ZP could devote one entire page for the low-bytes and another entire page for the high-bytes, yielding a total of 256 sixteen-bit items.
I hadn't thought about a 512 byte stack but you are right. A split stack could be made as large as 512 bytes entirely accessible with just the X register. However, 256 bytes is more than enough for me.
User avatar
GARTHWILSON
Forum Moderator
Posts: 8775
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Orthogonal 65c02 addressing modes

Post by GARTHWILSON »

Dr Jefyll wrote:
I think Garth means a split stack that's not in ZP could devote one entire page for the low-bytes and another entire page for the high-bytes, yielding a total of 256 sixteen-bit items. So it can double the size of the data stack. But for the sake of speed and reduced code size, the stack is usually placed in ZP, whether it's split or not. (Actually the speed issue is somewhat debatable, because zp,x and zp,y modes have a dummy cycle that makes them just as slow as abs,x and abs,y.)
Yes, that's what I meant. I forgot about the extra cycle in the ZP,X and ZP,Y addressing modes bringing the up to the same cycle count as ABS,X and ABS,Y (as long as the absolute ones do not involve a page boundary crossing); but the advantage of smaller code remains.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: Orthogonal 65c02 addressing modes

Post by Dr Jefyll »

GARTHWILSON wrote:
I forgot about the extra cycle in the ZP,X and ZP,Y addressing modes bringing the up to the same cycle count as ABS,X and ABS,Y (as long as the absolute ones do not involve a page boundary crossing); but the advantage of smaller code remains.
Oops, and we both forgot that, when using abs,x or abs,y mode, STA and certain R-M-W instructions suffer the one-cycle penalty whether there's a page crossing or not. So, locating a stack in ZP does result in a certain speed boost. (For a non-split stack in ZP, an additonal speed advantage can arguably be obtained by use of (zp,x) mode.)
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
Post Reply