YCPU: an imaginary 16-bit processor.

You can talk about almost anything that you want to on this board.

Moderator: Moderators

pops
Posts: 91
Joined: Sun Apr 04, 2010 4:28 pm

YCPU: an imaginary 16-bit processor.

Post by pops »

As a thought experiment, I've been dreaming up a 16-bit CPU. My goal is to create a relatively powerful processor with a comprehensive instruction set, but is limited to working on 16-bits of data at a time. The specification, which is hosted at Github, is released to the public domain under the CC0 waiver, and anyone may use it for any purpose without permission or attribution. Direct link to the YCPU Specification.

I've also implemented an emulator for this processor in C#, which is released under the MIT license. The emulator is also hosted at Github.

In this thread, I've been asking questions as the specification has matured. Thanks to everyone who has offered comments and suggestions and answered my questions: this community is exceptionally helpful.
Last edited by pops on Sun Mar 23, 2014 9:44 pm, edited 22 times in total.
User avatar
koitsu
Posts: 4203
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: Addressing modes for a fake cpu - what would you include

Post by koitsu »

Recommend you look at the WDC 65816, which is a 16-bit CPU fully backwards-compatible with the 6502, to get an idea of what addressing modes are useful.
zzo38
Posts: 1080
Joined: Mon Feb 07, 2011 12:46 pm

Re: Addressing modes for a fake cpu - what would you include

Post by zzo38 »

If R is register and I is immediate:

Code: Select all

I
R
[R]
[R+I]
[R+[I]]
[[R]+I]
[--R]
[R++]
This might be a usable set of addressing modes (assume the stack pointer is one of the eight general purpose registers, possibly so is the program counter (in which case an immediate value addressing mode isn't needed)).
[url=gopher://zzo38computer.org/].[/url]
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Addressing modes for a fake cpu - what would you include

Post by tepples »

You don't need to implement any addressing modes at all on most instructions. ALU operations such as addition can be register := register op register or register := register op constant. You only need addressing modes for the load and store instructions.

And even then, the only modes you really need are register+register and register+constant. Instead of having a more complicated address generator on the CPU, you can have the program running on the CPU calculate addresses with standard ALU instructions, which might let you run the rest of the CPU faster.

As for how offsets are interpreted: Is this 16-bit address space 65536 bytes (32768 words) or 65536 words? If 65536 bytes, what do you do with a 16-bit load from an odd address?
User avatar
Movax12
Posts: 529
Joined: Sun Jan 02, 2011 11:50 am

Re: Addressing modes for a fake cpu - what would you include

Post by Movax12 »

Look at MIPS maybe: http://en.wikipedia.org/wiki/MIPS_architecture

It does things quite a bit differently then you may be used to if you only have knowledge of 6502 and may give you some ideas.
User avatar
Dwedit
Posts: 4470
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Addressing modes for a fake cpu - what would you include

Post by Dwedit »

Having used both ARM and X86, ARM lets you do crazy stuff in address modes [r1 + r2 << r3], while X86 lets you use arbitrary memory with almost any instruction.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Addressing modes for a fake cpu - what would you include

Post by tepples »

Speaking of MIPS, I designed a 16-bit MIPS-inspired CPU called KIPS with 14 instructions while I was in college. (The thing was supposed to have 15, but I never got shift working.)

ALU ops: MOV, ADD, SUB, SLT (compare), AND, OR, XOR, two operands, second either a register or a 9-bit signed immediate value. These had two encodings: high nibble 8-F if the reg was
Other ops: LUI (load 16-bit immediate value shifted left 8; for use with OR to load a 16-bit value), LDR (load register with word at 6-bit offset from address in another register), STR (store), BNE/BEQ (add to PC if register is nonzero or zero), JSR (move PC to a register and add a 9-bit signed offset to PC), and RTS (move a register to PC). No flags; SLT puts the result in a register, and 32-bit quantities are added the same way 64-bit quantities are added on MIPS.

I seem to remember the instruction encoding looking something like this:

Code: Select all

FEDCBA9876543210  ALU opcodes, second operand constant
||||||||||||||||
|||||||||||||+++- ALU function code inspired by 74*381 ALU:
|||||||||||||     0=shift, 1=compare, 2=subtract, 3=add,
|||||||||||||     4=xor, 5=or, 6=and, 7=mov (use second operand
||||||||||+++---- Destination register
|||||||+++------- Second operand
||||+++---------- First operand
++++------------- 0

FEDCBA9876543210  ALU opcodes
||||||||||||||||
|||||||+++++++++- Second operand, 9-bit signed
||||+++---------- First operand and destination
|+++------------- ALU function code
+---------------- 1

FEDCBA9876543210  LDR/STR
||||||||||||||||
||||||||||++++++- Offset from address
|||||||+++------- Register containing address
||||+++---------- Data register
++++------------- Memory opcode

FEDCBA9876543210  Conditional branches (whether or not a reg is nonzero)
||||||||||||||||
|||||||+++++++++- Signed value to add to PC if check succeeds
||||+++---------- Register to check
++++------------- Branch opcode
pops
Posts: 91
Joined: Sun Apr 04, 2010 4:28 pm

Re: Addressing modes for a fake cpu - what would you include

Post by pops »

koitsu wrote:Recommend you look at the WDC 65816, which is a 16-bit CPU fully backwards-compatible with the 6502, to get an idea of what addressing modes are useful.
I'm thinking of a cpu with multiple general purpose registers, not an accumulator and two index registers. I realized while reading this document that despite months programming the 6502, I still have no idea what indexed indirect [ (value, x) ] addressing could be useful for, compared to indirect indexed [ (value),y ].
zzo38 wrote:If R is register and I is immediate:

Code: Select all

...
[--R]
[R++]
The inclusion of [R++] in place of Immediate addressing is clever. Sold. Where would I use --R?
tepples wrote:As for how offsets are interpreted: Is this 16-bit address space 65536 bytes (32768 words) or 65536 words? If 65536 bytes, what do you do with a 16-bit load from an odd address?
I hadn't thought of this problem... and after spending the afternoon musing about it, I still have no idea what the correct solution is. My initial thought is that a 16-bit load from an odd address shouldn't be a problem, just load the low byte from the odd address and the hi byte from the even address.

Would the better solution be to ignore the bit0-address line when loading 16-bit? What about the PC? Loading [PC++] should evaluate to PC += 2, I guess. But that's completely counter-intuitive. How do other CPUs handle this?
User avatar
Movax12
Posts: 529
Joined: Sun Jan 02, 2011 11:50 am

Re: Addressing modes for a fake cpu - what would you include

Post by Movax12 »

pops wrote:I still have no idea what indexed indirect [ (value, x) ] addressing could be useful for, compared to indirect indexed [ (value),y ].
It's generally pretty useless.
lidnariq
Posts: 10677
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Addressing modes for a fake cpu - what would you include

Post by lidnariq »

pops wrote:I still have no idea what indexed indirect [ (value, x) ] addressing could be useful for
Indexing into an array of pointers. e.g. C's argv[n][0].
The inclusion of [R++] in place of Immediate addressing is clever. Sold. Where would I use --R?
PIC assembly includes a set of special registers (and instructions) that provide preinc, postinc, predec, and no change.
In any case, postinc and predec are obvious pairs for a software stack.
Would the better solution be to ignore the bit0-address line when loading 16-bit? What about the PC? Loading [PC++] should evaluate to PC += 2, I guess. But that's completely counter-intuitive. How do other CPUs handle this?
IMO, you should forsake bytes altogether and natively address 65536 words.
User avatar
Movax12
Posts: 529
Joined: Sun Jan 02, 2011 11:50 am

Re: Addressing modes for a fake cpu - what would you include

Post by Movax12 »

lidnariq wrote: Indexing into an array of pointers. e.g. C's argv[n][0].
But it only works in zero page .. zero page is normally too precious to waste on setting up arrays of pointers. Relevant discussion: http://forum.6502.org/viewtopic.php?f=2&t=2538
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Addressing modes for a fake cpu - what would you include

Post by tepples »

I think the only place I've used (d,x) on the NES is in my music engine, where I store a bunch of data pointers per channel on zero page, indexed by channel X (where X=0, 4, 8, 12). In fact, apart from cases like this where you have multiple streams of data accessed in parallel, it's so otherwise unused that the Missile Command PCB repurposes it as a "screen access" instruction, with a circuit to recognize the (d,x) opcodes and temporarily remap the VRAM for individual pixel access.
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Re: Addressing modes for a fake cpu - what would you include

Post by Bregalad »

I think the only place I've used (d,x) on the NES is in my music engine, where I store a bunch of data pointers per channel on zero page, indexed by channel X (where X=0, 4, 8, 12).
Same here. Looks like this addressing mode is very specific to music ^^

I think it happened to me once to need plain indirect without indexing on 6502, and that I've used ($xx,X) instead of ($xx),Y because scrapping X was better than scrapping Y in that particular situation.
pops
Posts: 91
Joined: Sun Apr 04, 2010 4:28 pm

Re: Addressing modes for a fake cpu - what would you include

Post by pops »

lidnariq wrote:
Would the better solution be to ignore the bit0-address line when loading 16-bit? What about the PC? Loading [PC++] should evaluate to PC += 2, I guess. But that's completely counter-intuitive. How do other CPUs handle this?
IMO, you should forsake bytes altogether and natively address 65536 words.
That's an interesting idea - but that would completely preclude byte access. I suppose you could still emulate byte load and store with masking and shifting. But you would need an extra bit of address to select the hi or lo byte of a 16-bit word. What about chars and strings?

Here's an alternative, although I don't necessarily think it's better: data access is byte-aligned, instruction access is word-aligned. There's 0x10000 bytes of data and 0x8000 words of instructions which share the same space.
User avatar
Dwedit
Posts: 4470
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Addressing modes for a fake cpu - what would you include

Post by Dwedit »

Separate instruction and data memory GO!
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
Post Reply