Internal busses are precharged to $FF during Φ2 and then connected to one of the ALU input latches in the immediately following Φ1, during which the nodes are floating. This forces $FF onto the ALU input by swamping it with charge from physically larger nodes. A register (X, Y, SP or PCH) is routed to the other ALU input and decremented by adding $FF (-1).
Temporarily turning your bus into a DRAM to stuff a value into an ALU == living your best life
An FPGA is not an ASIC. Latches are totally valid design choices and they take less silicon area if doing a custom layout. The thing is that an FPGA has a lot of time/money spent on getting the clock network and tooling for that clock network correct in a flopped digital style, and you obviate that by trying to force latches.
I'm not a EE but four transistors for a D-FF is hard to beat. Z-80 other contemporaries also used dual phase clocks. Obviously the downsides outweighed the transistor overhead eventually.
There was a "modern" instantiation of this by Intrinsity (got acquired by Apple) whose "FAST-14" [1] dynamic logic used a four-phase clock. That was pretty cool and they had some (for the time) insanely fast products. I wonder if that logic style would have been feasible in the 6502's time frame.
6502 and its variants were used in many platforms, particularly video game systems and TV computers like the Apple II family, BBC Micro, Commodore Pet/VIC-20/64, Atari 400/800, Nintendo Entertainment System/Famicom, and TurboGrafx-16/PC-Engine. Introductory information about it tends to be oriented toward those platforms rather than the chip itself.
https://skilldrick.github.io/easy6502/ might be a good starting point if you're already familiar with assembly language in general (it's styled as an assembly language tutorial, but I'm not really in a position to know how good it is at that).
Thanks. I was reading and listening to Chuck Peddle's talks last hour about his work at Motorola and MOS. At the age of 81, he still gives talks. Very inspiring stuff.
It's one of the famous 8-bitters (possibly the famousest). The Wikipedia page is probably a decent start, for overwhelmingly way too much there is 6502.org.
MOS Technology made it popular by pricing it cheaply and giving engineering samples to young, bearded hippies like the Woz. It was cheap and accessible when the other microcontrollers were not yet so much.
It is OK to program, not exactly unpleasant, but it is quirky. I did a linker for the Apple II in about 4k lines of assembly code, because their assembler produced a decent symbol dictionary but didn't come with a linker. That was the largest single assembly module I did for the 6502.
I also worked on a compiler for something like B, but never finished. Code generation was just too wonky. Hand written 6502 is OK once you know the idioms.
You sound like a veteran, so I'm sure you know this and made a typo, but anyway please let me clarify: the 6502 (and Z80, 8080 etc mentioned here) are not microcontrollers. They are microprocessors.
Microcontrollers generally integrate more of the things that the are needed in order to build a computer from a "naked" processor, into the same chip. Modern microcontrollers almost always contain onboard flash memory for code and data storage, as well as SRAM and peripherals.
A 6502 has none of that, and you need many more additional chips on the board to make it into a functional computer.
What do you mean? Is code generation for the 6502 unusually difficult, even compared to other 8-bit processors (e.g. 8080/Z80)? I'm sure code generation for an 8-bit processor is difficult compared to a 32-bit processor.
It's been a while since I've read about this, and I'm far from a 6502 expert, but I think the biggest issues are:
1) There's not a cheap, straightforward way to get a conventional frame pointer (i.e. indexable pointer to local variables on the stack). I imagine one could do something with the indexed zero-page modes, but I'm not sure how well that works in practice.
2) None of the registers are large enough to hold a full memory address, which considerably complicates any pointer arithmetic beyond increment/decrement.
I'm even less familiar with Z80 than I am with 6502, but I gather that the IX and IY index registers were added to it to address similar limitations in the 8080 architecture.
but I gather that the IX and IY index registers were added to it to address similar limitations in the 8080 architecture
The 8080 was much better than the 6502 in terms of 16-bit registers, even without IX and IY.
The architecture was:
A an 8 bit accumulator
B C two 8 bit regs or combined 16 bit
D E two 8 bit regs or combined 16 bit
H L two 8 bit regs or combined 16 bit
I did a lot of Z80 programming and I usually ignored IX and IY. They were useful for certain things. But they were slower than the 8080's registers, because IIRC they needed an extra opcode byte.
The Z80 did, however, add lots of neat stuff that used the existing 8080 architecture registers.
E.g., here's a single instruction equivalent of today's memmove() Unix library function. Do this:
BC <-- stuff a 16 bit count into it
DE <-- stuff a 16 bit destination address into it
HL <-- stuff a 16 bit source address into it
then do the LDIR instruction and you get a memory copy in a single instruction. Up to 64 K bytes, which was the entire address space.
IIRC the instruction was interruptible on a byte-by-byte basis, so it's not like you ruined your interrupt response time.
> IIRC the instruction was interruptible on a byte-by-byte basis, so it's not like you ruined your interrupt response time.
Yes, LDIR is basically the same as the LDI instruction with the little difference that the PC is reset to the start of the LDIR instruction until BC is 0. It's basically a microcoded LDI+conditional jump, and interrupt handling, DRAM refresh etc... happens at each step, since from the CPU's point of view, it's just executing a lot of single instructions while LDIR is running.
On 6502 you are usually better off with bytecode (SWEET16, p-code) or threaded code (FORTH) to improve code density. There are even people making new languages (Cowgol, PLASMA) that are self-hosted on the 6502!
Original 16bit x86 was 8080/8085 assembly upgrade to 16bit (source code compatible to the 8080), and the Z80 was a upgraded clone for the 8080. You can get a assembly code for a 8080 and just compile it for the 8086 and it would work.
So, it's logic that compilers that target Z80/8080/8085, generate something similar to what any compiler would do on x86.
> I imagine one could do something with the indexed zero-page modes, but I'm not sure how well that works in practice.
That's it exactly. Page zero essentially becomes 128 16-bit registers. But of course a lot of things are hungry for page zero resources. And it isn't exactly speedy. So you could put a pointer in page zero, and reach 256 bytes off of it.
Well, it was mainly code bloat issues caused by the nature of the indexed addressing reach and the need for zero-page indirection. The 6502 instuction set is very simple, and the register complement limited.
I don't mean that as criticism, but as an acknowledgment of how the designers made tradeoffs within the die area budget. A good comparison is the Motorola 6800 which had about the same transistor budget but a much more regular architecture.
If you study either of those, then afterwards an ATMega168 is going to look resource rich in comparison.
Temporarily turning your bus into a DRAM to stuff a value into an ALU == living your best life