Page 1 of 4
MyCPU - not a TTL 6502
Posted: Tue Mar 02, 2010 8:29 pm
by BigEd
Anyone interested in homebrew CPUs might like Dennis Kuschel's MyCPU
http://mycpu.selfhost.it/epj03.htm
which is inspired by 6502 but not binary compatible. The computer is a stack of boards with TTL and EPROMS, the CPU has familiar A, X and Y registers, a zero page and a page one stack. He brings out separate memory control signals for program and for data accesses, which gives it a possible 64k+64k space - it seems there's also bank switching including special handling for pages zero and one.
He's written an emulator, ported CC65, and ported C64 basic and other things - this is a major project, but all open source for keen self-builders! And it's currently active.
I came to his page from this catalogue:
http://3.14.by/en/read/homemade-cpus
Posted: Tue Mar 02, 2010 11:40 pm
by ElEctric_EyE
Fascinating stuff, it really is. To design a custom 6502 type CPU is my personal holy grail, and I will be there soon. Everything I am learning now is for this purpose. Thanks for the link.
Posted: Wed Mar 03, 2010 2:55 am
by ElEctric_EyE
I was at work, seems they turned the firewall off. I was surprised, but I had to keep it short nonetheless. Now at home, so I can comment abit more.
Too bad it's not pin compatible with the 6502, but I guess that's not really important in this case, especially when you consider the fact that he can compile/assemble his own software directly off his system. He said it was an evolutionary step to finally lose the PC... Interesting he mentioned the commodore 64, any Basic programs written for it are backwards compatible...
Anyway, when I do my own 6502 style CPU, I plan on adding more reg's, as many I can... If I can make it similar to the WDC65C02 (big if, doubtful except for STZ) with 212 opcodes, that is leaving an open door for 44 more possibilities... But IMO, you can't design a CPU and not design/modify the assembler to take advantage of the mod's. This guy has done that too. Kudos to him. But he needs to start working with CPLDs and FPGAs and speed that puppy up.
Posted: Wed Mar 03, 2010 8:59 pm
by Ruud
Too bad it's not pin compatible with the 6502
My opinion as well. Mine is and it will run on the clock fed by the system board. No extra internal or whatever.
Anyway, when I do my own 6502 style CPU,
Any schematics yet? I'm still busy but if interested, I'll upload mine to my site.
that is leaving an open door for 44 more possibilities...
If you are interested, I'll share an idea that wil give you a multiple of 256 opcodes.
But he needs to start working with CPLDs and FPGAs and speed that puppy up.
Check his site again, he already has! But if you want speed, unfortunately you have to. The old 74LS IC's are only good up to 25 MHz. But I will start to build my TTL-6502 ASAP.
Posted: Wed Mar 03, 2010 9:42 pm
by BigEd
But he needs to start working with CPLDs and FPGAs and speed that puppy up.
Check his site again, he already has!
Oops, I linked to an article rather than his site: here's his FPGA-based MyCPU page:
http://mycpu.selfhost.it/mycpucompact.htm
that is leaving an open door for 44 more possibilities...
If you are interested, I'll share an idea that wil give you a multiple of 256 opcodes.
Are you familiar with the ST-7?
(pdf, page 63 onward) It's not entirely unlike a 6502: the X register is pushed on interrupts, and the Y register and indirect modes come into play using prefix bytes.
Posted: Wed Mar 03, 2010 9:53 pm
by ElEctric_EyE
Anyway, when I do my own 6502 style CPU,
Any schematics yet? I'm still busy but if interested, I'll upload mine to my site.
I have been working with CPLDs successfully, that is all I can offer ATM. I haven't started on a design, but I am doing alot of reading...If you give me a schematic I can replace the discrete logic with a CPLD. Parts of the schematics that require EEPROMs will have to use FPGA's from what I've read.
that is leaving an open door for 44 more possibilities...
If you are interested, I'll share an idea that wil give you a multiple of 256 opcodes.
I am interested, PM me the details? You are meaning banked opcodes?
Posted: Wed Mar 03, 2010 9:57 pm
by GARTHWILSON
If it is at all related to 6502 work, I hope you'll post it here for everyone to benefit from.
Posted: Wed Mar 03, 2010 9:58 pm
by ElEctric_EyE
But he needs to start working with CPLDs and FPGAs and speed that puppy up.
Check his site again, he already has!
Oops, I linked to an article rather than his site: here's his FPGA-based MyCPU page:
http://mycpu.selfhost.it/mycpucompact.htm
ooooh I missed that part, man that is sweet. Jeez, and that is VERY recent 3/2/2010! How fast is the FPGA version running?
Posted: Thu Mar 04, 2010 1:59 pm
by Ruud
If it is at all related to 6502 work, I hope you'll post it here for everyone to benefit from.
The core of my Intrusction Decoder (ID) is a bunch of AT29C010 EEPROM's. Their outputs control various enable inputs, clock inputs etc. etc. of the various buffers, latches and the ALU. Their inputs:
- opcode
- a 4 bit counter: PHI0 + 3 outputs of a 74LS393
- special input bit: telling there is a reset, IRQ or NMI going on.
- branch input, needed for branches.
The idea is to use extra inputs for extra opcodes. For example, two extra inputs give us a total of 1024 opcodes. Every input needs one D-Flipflop (half a 7474). D and CLK are connected to Ground. The PREset and CLeaR inputs are connected to an output of the ID. Now reserve an illegal opcode for every flipflop. Executing such a new opcode presets the according flipflop. The micro-code for the next opcode is now read from another part of the EEPROM's (= other set of opcodes). Remark: this 2nd opcode has to to reset all set flipflops at the and of the instruction.
That's all, have fun!
Posted: Thu Mar 04, 2010 7:27 pm
by BigEd
Aha - that's a prefix byte, then. For instructions used rarely, or which take a bit longer, could be a good tradeoff. For example, 16-byte operations will take an extra cycle or two, as will indirect operations.
I think a prefix byte is lot more pleasant than a mode bit, but in some ways could be similar.
A prefix system could be useful for
- access to extra registers or wider registers
- wider operands (16 bit relative offsets)
- extended pointers (instead of a bank byte)
Posted: Thu Mar 04, 2010 9:05 pm
by Ruud
I think a prefix byte is lot more pleasant than a mode bit,
Yes, prefix byte. Forgot that name. But this 'mode bit' idea is great as well. It simply means you set the needed flipflops and go on with a complete different different opcode set. If done, you reset the flipflops. And I don't see any reason why you cannot mix both ideas.
I'm busy to prepare my designs plus an HTML that will explain the designs.
Posted: Thu Mar 04, 2010 9:14 pm
by BigEd
Some people's experience with the 65816 is to find the mode bits problematic: for one thing, each routine needs to be written with some assumption about the mode, or set/restore the mode. Either choice is less convenient than having opcodes which do exactly what they say.
The decimal mode is a case in point: if there was lots of opcode space, having decimal add and decimal subtract would avoid the need to set the bit, or to adopt a convention about whether it is set or not. The 65C02, I think, clears decimal mode on interrupt, so the interrupt routine can do arithmetic without clearing a flag. That's indicative of the kind of distraction you get from modes.
Modes are great if you haven't enough opcodes!
(Another case that springs to mind: wasn't there a linux kernel bug deriving from the x86 having a mode for which direction string operations proceed? Ah yes,
here)
Posted: Thu Mar 04, 2010 9:43 pm
by GARTHWILSON
Some people's experience with the 65816 is to find the mode bits problematic: for one thing, each routine needs to be written with some assumption about the mode, or set/restore the mode. Either choice is less convenient than having opcodes which do exactly what they say.
At risk of sounding like a broken record, I will say again for the benefit of our new members that what I found when I wrote my 65816 Forth kernel was that I almost never had to change the modes. Taking the accumulator out of 16-bit mode was really only done for I/O, and there are almost no cases of taking the index registers out of 8-bit mode. (The only one I can think of is for MVN and MVP memory-move and -fill instructions.) After COLD start, emulation mode was never touched at all. Neither was decimal mode. (Forth converts to and from any base without using decimal mode.) Since I made it to only use the first 64K of address space, the bank registers were never touched either. Since I wasn't latching or decoding the address bank, I could have even used the bank registers as a separate pair of limited-use scratchpad registers.
As far as routines starting with assumptions about the modes, it was
always 16-bit accumulator, 8-bit index registers, non-decimal, and native (non-emulation) mode. No exceptions. (There was never a reason for an exception, so this did not constitute any compromise.)
When I did make temporary mode changes within a routine, I used macros to replace the confusing REP and SEP instructions, and called them ACCUM_8, ACCUM_16, INDEX_8, and INDEX_16. It makes it much more clear and has no memory or speed penalty.
Posted: Thu Mar 04, 2010 9:48 pm
by BigEd
Hi Garth
Thanks, that's a useful reminder. You were able to make some choices which you could apply globally, so you could largely set the modes and forget. It might be that decimal mode is similar: it's used never, or always, or in some very specific subroutines. But I still find the 65816's modes disorientating - perhaps due to lack of experience.
Cheers
Ed
8 Bits or 16?
Posted: Thu Mar 04, 2010 11:30 pm
by BigDumbDinosaur
Some people's experience with the 65816 is to find the mode bits problematic: for one thing, each routine needs to be written with some assumption about the mode, or set/restore the mode. Either choice is less convenient than having opcodes which do exactly what they say.
At risk of sounding like a broken record, I will say again for the benefit of our new members that what I found when I wrote my 65816 Forth kernel was that I almost never had to change the modes. Taking the accumulator out of 16-bit mode was really only done for I/O, and there are almost no cases of taking the index registers out of 8-bit mode. (The only one I can think of is for MVN and MVP memory-move and -fill instructions.) After COLD start, emulation mode was never touched at all. Neither was decimal mode. (Forth converts to and from any base without using decimal mode.) Since I made it to only use the first 64K of address space, the bank registers were never touched either. Since I wasn't latching or decoding the address bank, I could have even used the bank registers as a separate pair of limited-use scratchpad registers.
As far as routines starting with assumptions about the modes, it was
always 16-bit accumulator, 8-bit index registers, non-decimal, and native (non-emulation) mode. No exceptions. (There was never a reason for an exception, so this did not constitute any compromise.)
When I did make temporary mode changes within a routine, I used macros to replace the confusing REP and SEP instructions, and called them ACCUM_8, ACCUM_16, INDEX_8, and INDEX_16. It makes it much more clear and has no memory or speed penalty.
In my current POC ROM, I immediately switch the '816 to native mode. The first significant code after reset and the mode switch is a RAM page decoding test, which is done with all registers set to 16 bits. After that, hardware setup is done, and has to take place with all registers in 8 bit mode to avoid unwanted overlapping writes. Ditto for hardware access during routine I/O.
Where a 16 bit accumulator seems to be most valuable is in moving word-sized values around, as well as performing math. The 16 bit index registers are obviously of considerable value in working over large memory ranges. However, running all registers in 16 bit mode all the time isn't practical in a lot of large-scale applications.
That said, it seems to me the MPU's design would have been better served if effective register widths were determined by opcode rather than by flipping status register bits. This is a case where a prefix byte preceding the opcode would tell the MPU to do a 16 bit load or store.
The use of the status register to determine register widths complicates the design of a machine code monitor, as the monitor has no way of knowing if a load immediate instruction is 8 or 16 bits. Compromises, compromises...