6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Thu May 09, 2024 7:28 am

All times are UTC




Post new topic Reply to topic  [ 11 posts ] 
Author Message
PostPosted: Thu Jun 16, 2022 6:27 pm 
Offline

Joined: Sun Oct 03, 2021 2:17 am
Posts: 114
I'm having a hard time following https://llx.com/Neil/a2/opcodes.html (bold emphasis mine):

Quote:
Many of the gaps in this table are easy to understand--for example, immediate mode makes no sense for any instruction other than LDX. It could argued that two gaps aren't really gaps at all: "STX A" and "LDX A" are missing, but their slots are occupied by TXA and TAX, which makes sense. Less understandable are the lack of "DEC A" and "INC A" (whose slots are occupied by DEX and NOP respectively) and "STX abs,Y" (whose slot is unassigned).

(Wild unwarranted speculation time: Perhaps there isn't really an "accumulator mode," but rather a set of unrelated single-byte opcodes, some of which semi-coincidentally happen to behave as if they were an accumulator mode for other instructions.)

The lack of immediate mode for instructions other than LDX does makes sense to me; that would be self modifying code (not that that is always a bad thing :p) Thinking of TXA and TAX as occupying the slots for STX A and LDX A makes sense too, because the spirit of those un-assembleable mmenmonics is the same as those respective transfer instructions. I also agree with the author that the lack of DEC A and INC A are harder to understand, but I am confused why he thinks of the slots as being occupied by DEX and NOP:

  • INC A clearly does not do the same thing as NOP, so these instructions are different in spirit: one has an effect, the other doesn't.
  • DEC A is operating on the accumulator, but DEX operates on the X index register. So the spirit of these instructions is similar but not quite the same; they do slightly different things.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 16, 2022 7:25 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8432
Location: Southern California
I'm having a little trouble understanding where you're trying to go with this. Are you aiming to make a processor yourself, and trying to streamline the instruction decoder as much as possible? Otherwise, for just programming (except for some parts of SMC), or even writing an assembler or a compiler, or for building a computer, we don't really need to pay attention to many of the things you seem to be so focused on. That's why there's nothing about them in the 6502 primer. (There's nothing wrong with being fascinated of course; but otherwise maybe we can steer you in a direction that will result in faster progress in the things that matter more.) I remember many of the op codes from my early days of hand-assembly; but since I started using good assemblers 35 years ago, it has virtually never really mattered what the op codes for various instructions and addressing modes are and how they're arranged in the op-code table. I have not paid any attention to what groups I, II, and III are. I don't need to.

That page makes good observations, but has some confusing notation. 'A' (capital) generally means "accumulator," but he seems to be using it for "absolute" which elsewhere is 'a' (lower-case), or 'abs' to be more clear. DEC A (decrement accumulator) is often shortened to DEA, op code $3A. DEC abs is op code $CE. STX abs and LDX abs have op codes $8E and $AE, respectively.

As for his comment, "The only irregularity is the absence of the nonsensical immediate STA instruction," I kind of wish there were an STA # (and STX # and STY #). It would not work in ROM; but if in RAM, the operand field would be the one-byte variable itself. There would be no need to take variable space elsewhere.

_________________
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?


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 16, 2022 9:44 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10800
Location: England
I think there are (at least) three levels of engagement with an early micro like the 6502: there's how to use it, which is the sort of thing the primer is aimed at; there's how it was conceived, or designed, or specified, which is where we get questions about missing instructions or desirable extensions; and there's how it was implemented, which is where we get to understand about some of the 'internal operation' cycles, and any 'extra' memory accesses, and the 'undocumented' opcodes.

I think Neil Parker's Instruction Set Decoded, as linked in the head post, is sitting somewhere in the middle level there, but straddling also the lower level. Which is to say, opcode assignment isn't purely a question of fitting up to 256 values into a big table: to make the implementation sensible, or even minimal, you need regularity in your instruction set and also regularity in the encoding of the instruction set.

But the whole instruction set isn't regular - there are always going to be a few combinations which don't fit in or which don't make sense - so those are likely to be assigned in such a way that the implementation has an easy time decoding them and doing the right actions.

So it's at the lower level - the level where visual6502 is so useful - that we can find answers to this kind of question, I think. Some NOR gate in the 'random logic' area might be combining or modifying some terms in order to produce a needed behaviour.

Studying the machine at this level is interesting, but can also be useful, either to make a compact an efficient re-implementation, or perhaps an assembler or disassembler, or an emulator, or indeed to build some other CPU using what we've learnt.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 16, 2022 9:50 pm 
Offline

Joined: Sun Oct 03, 2021 2:17 am
Posts: 114
GARTHWILSON wrote:
I'm having a little trouble understanding where you're trying to go with this. Are you aiming to make a processor yourself, and trying to streamline the instruction decoder as much as possible? Otherwise, for just programming (except for some parts of SMC), or even writing an assembler or a compiler, or for building a computer, we don't really need to pay attention to many of the things you seem to be so focused on. That's why there's nothing about them in the 6502 primer. (There's nothing wrong with being fascinated of course; but otherwise maybe we can steer you in a direction that will result in faster progress in the things that matter more.)
Nothing like that - just curious :)
GARTHWILSON wrote:
That page makes good observations, but has some confusing notation. 'A' (capital) generally means "accumulator," but he seems to be using it for "absolute" which elsewhere is 'a' (lower-case), or 'abs' to be more clear. DEC A (decrement accumulator) is often shortened to DEA, op code $3A. DEC abs is op code $CE. STX abs and LDX abs have op codes $8E and $AE, respectively.
I don't think you mean the two instructions that I put after the bullet points above are actually using absolute addressing, because that row is filled in the table. I still don't know why their slots are occupied with DEX and NOP though. :?
GARTHWILSON wrote:
As for his comment, "The only irregularity is the absence of the nonsensical immediate STA instruction," I kind of wish there were an STA # (and STX # and STY #). It would not work in ROM; but if in RAM, the operand field would be the one-byte variable itself. There would be no need to take variable space elsewhere.[/color]

So you do want the self modifying code? Fair enough. 8)


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 16, 2022 10:13 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8432
Location: Southern California
jeffythedragonslayer wrote:
GARTHWILSON wrote:
As for his comment, "The only irregularity is the absence of the nonsensical immediate STA instruction," I kind of wish there were an STA # (and STX # and STY #). It would not work in ROM; but if in RAM, the operand field would be the one-byte variable itself. There would be no need to take variable space elsewhere.

So you do want the self modifying code? Fair enough. 8)

An STA#, if it existed, would not be SMC. You could do a similar thing with STA * (where * is the current address), but then you'd have to re-set it to point to itself again before the next time that line is run.

_________________
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?


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 16, 2022 11:04 pm 
Offline

Joined: Wed Aug 21, 2019 6:10 pm
Posts: 217
jeffythedragonslayer wrote:
I'm having a hard time following https://llx.com/Neil/a2/opcodes.html (bold emphasis mine):

Quote:
Many of the gaps in this table are easy to understand--for example, immediate mode makes no sense for any instruction other than LDX. It could argued that two gaps aren't really gaps at all: "STX A" and "LDX A" are missing, but their slots are occupied by TXA and TAX, which makes sense. Less understandable are the lack of "DEC A" and "INC A" (whose slots are occupied by DEX and NOP respectively) and "STX abs,Y" (whose slot is unassigned).
...

The lack of immediate mode for instructions other than LDX does makes sense to me; that would be self modifying code (not that that is always a bad thing :p) Thinking of TXA and TAX as occupying the slots for STX A and LDX A makes sense too, because the spirit of those un-assembleable mmenmonics is the same as those respective transfer instructions. I also agree with the author that the lack of DEC A and INC A are harder to understand, but I am confused why he thinks of the slots as being occupied by DEX and NOP. ...


Because if you take %110.bbb.10 (Group 2 DEC) and %111.bbb.10 (Group 2 INC) and %aaa.010.10 (Group 2 Accumulator addressing) together, you get %110.010.10 ($CA) and %111.010.10 ($EA), respectively, as the "natural slots" for DEC A and INC A.

Then when you turn to the actual instruction set, those are not DEC A and INC A, they are, instead, DEX and NOP.

So in other words, DEX and NOP are performed by opcodes that according to the general pattern of group %aaabbb10 instructions would be DEC A and INC A. So the 65C02 ended up locating these useful operations at 000.110.10 ($1A) and 001.110.10 ($3A), where aaa.110.10 is not an implemented address mode in Group 2 in the NMOS 6502 instruction set.


Last edited by BruceRMcF on Fri Jun 17, 2022 10:12 pm, edited 2 times in total.

Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 16, 2022 11:55 pm 
Offline

Joined: Sun Oct 03, 2021 2:17 am
Posts: 114
GARTHWILSON wrote:
An STA#, if it existed, would not be SMC. You could do a similar thing with STA * (where * is the current address), but then you'd have to re-set it to point to itself again before the next time that line is run.

So it's only considered SMC if the first byte of an instruction is being modified? Immediate mode instructions are 2 or 3 bytes long. The first byte contains the opcode, and the second (and third, if there is one) bytes are the constant operand. Where exactly is A going in STA#?

BruceRMcF wrote:
Because if you take %110.bbb.10 (Group 2 DEC) and %111.bbb.10 (Group 2 INC) and %aaa.010.10 (Group 2 Accumulator addressing) together, you get %110.010.10 ($CA) and %111.010.01 ($EA), respectively, as the "natural slots" for DEC A and INC A.

Then when you turn to the actual instruction set, those are not DEC A and INC A, they are, instead, DEX and NOP.

So in other words, DEX and NOP are performed by opcodes that according to the general pattern of group %aaabbb01 instructions would be DEC A and INC A. So the 65C02 ended up locating these useful operations at 000.110.10 ($1A) and 001.110.10 ($3A), where aaa.110.10 is not an implemented address mode in Group 2 in the NMOS 6502 instruction set.

Excellent explanation, kind of like what BigEd was saying about the instruction set not being regular. Thank you. :)


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 16, 2022 11:59 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8432
Location: Southern California
jeffythedragonslayer wrote:
GARTHWILSON wrote:
An STA#, if it existed, would not be SMC. You could do a similar thing with STA * (where * is the current address), but then you'd have to re-set it to point to itself again before the next time that line is run.

So it's only considered SMC if the first byte of an instruction is being modified? Immediate mode instructions are 2 or 3 bytes long. The first byte contains the opcode, and the second (and third, if there is one) bytes are the constant operand. Where exactly is A going in STA#?

Oh, I see what you're saying. But in this case, the operand field getting modified would not be an operand; instead, it would be the data space. The instruction would never read its own operand field. Instructions in other parts of the program would read that field as data, a variable. (They could write to it too, just like any other variable.)

_________________
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?


Top
 Profile  
Reply with quote  
PostPosted: Fri Jun 17, 2022 3:23 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1928
Location: Sacramento, CA, USA
GARTHWILSON wrote:
Oh, I see what you're saying. But in this case, the operand field getting modified would not be an operand; instead, it would be the data space. The instruction would never read its own operand field. Instructions in other parts of the program would read that field as data, a variable. (They could write to it too, just like any other variable.)

The 6800 actually allows it, although I have never used that undocumented feature, and I doubt that it would be easy to find an assembler with that feature built-in.

I also like the 6800's documented ability to do things like LDX 0,X , but it has a ton of weaknesses in other areas to offset that advantage.

_________________
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)


Top
 Profile  
Reply with quote  
PostPosted: Sat Jun 18, 2022 12:46 am 
Offline

Joined: Wed Aug 21, 2019 6:10 pm
Posts: 217
GARTHWILSON wrote:
... Oh, I see what you're saying. But in this case, the operand field getting modified would not be an operand; instead, it would be the data space. The instruction would never read its own operand field. ...


This may be why it might be viewed as nonsensical at a certain level of detail ... it may be that the operation executes by letting the "get the next instruction byte" process run and then grabs the data from the internal register where "the next instruction byte" lands.

In that case, "no, do a write, not a read" would not end up with the data being written to memory, since the "get the next instruction byte" hardware is likely implemented as a read-only process ... and anything written to the internal register where "the next instruction byte" lands seems likely to be over-written by the fetch of the next opcode.


Top
 Profile  
Reply with quote  
PostPosted: Sat Jul 09, 2022 4:34 pm 
Offline
User avatar

Joined: Tue Aug 11, 2020 3:45 am
Posts: 311
Location: A magnetic field
I like jeffythedragonslayer's recent questions. I presume there is an interest to really understand 6502 from the view of a compiler writer, virtual machine implementer and at the transistor level. This question is perhaps the most intriguing and shows a particular thoroughness. In particular, it reveals a binary incompatible 6502 variant with less transistors and more functionality.

I regarded STA immediate as the Technetium of the 6502's opcode chart. It never occurred to me that it has a useful semantic - as implemented by the 6800 designers. As noted in a recent narrated animation about the history of 6502 (and 6800), the designers were very focused on embedded applications, such as automotive. In this context, there is a strict division between program and data. From this view, store immediate is worthless - or even undesirable behavior.

Another example of this code/data separation is the functionality of NMOS 6502 RDY signal which only works when reading. This is sufficient for process control from a cheap ROM. In this arrangement, the system cycle time is limited by the worse path in the I/O segment. If you have, for example, eight RIOTs or ten VIAs, I/O speed is fairly equally matched with the processor. Just add another cycle or two to cover slow ROM. That is more adequate for stepper motors and similar. However, if you want the fastest, general purpose computer and you want to interface 2MHz processor with 1MHz peripheral, a RDY signal which is ignored during write cycles is an annoying impediment.

It was corrected in 65C02 but this only makes a three way corner case. (RDY stretching, write cycles, NMOS: choose any two.) Unfortunately, I've been affected by this problem. Despite expert advice, people insist on using dodgy, random components. Therefore, I've made sure that my work is NMOS compatible. This is quite easy in software. Like the 6502 designers, I was concerned about NMOS compatible slow ROM access. Unlike the 6502 designers, I didn't clock stretch I/O correctly. It is a regrettable decision made downstream from the 6800 and 6502 design decisions. It was caused because I wanted maximum performance rather than a cheap and cheerful system.

In the very hypothetical situation of designing an 8 bit instruction set where more than 1/3 of the opcodes are unused, I'd probably leave STA immediate unallocated and put all of the fiddly exceptions (LDX#, LDY#, INX, DEX, INY, DEY, CLV) into one group. I'd also make RegX and RegY down counters so that DEX and DEY would be one cycle. However, that probably requires more transistors.

_________________
Modules | Processors | Boards | Boxes | Beep, Beep! I'm a sheep!


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

All times are UTC


Who is online

Users browsing this forum: No registered users and 10 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: