YCPU: an imaginary 16-bit processor.

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

Moderator: Moderators

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 »

Just making it always use 16-bit bytes, is I think OK.
[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 »

pops wrote:What about chars and strings?
In Java, char is 16-bit. You need that many bits to store ideograms anyway, like this:

塊魂斗羅

what does that spell?
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 »

Please do not turn the CPU into an IBM S/360. Don't know what I'm talking about? Try CUUTF and CUTFU. Don't let Tepples try to convince you otherwise blabbing on about Java and ambiguous types like "char" (re-focus, Tepples).
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 »

Here are my current thoughts on the 8-bit/16-bit divide.

Address space is 0x10000 bytes. Neither the PC nor pointers need be word-aligned. The registers are all 16-bit internally, but they can operate on 8-bits of data at a time when you set a specific bit in the flag register. There is one bit to select 8-bit/16-bit data registers, and another bit to select 8-bit/16-bit index registers. Using a register as data/index while 8-bit mode is set will zero out the upper 8-bits of that register. Immediate values, as well as values pushes onto the stack, are ALWAYS 16-bit, although the upper 8-bits of these values will be unused (masked with 0x00FF) when 8-bit mode is enabled.

This is exactly how the 65802 used its flag register. See attached image.
Attachments
Screen Shot 2014-03-06 at 2.16.50 PM.png
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 don't know what are your goals in designing this CPU, but you have to keep in mind that even though it might be "fake" right now, you might want to implement it in hardware some day, so you'll have to keep this in mind in order to avoid making this task hell. Implementing a CPU in hardware is an extremely fun and interesting project, I've done it last year as an university project and it's one of the things I enjoyed the most doing ! It was however long and challenging. It was also hard to test, and it was quite different as I had to implement a very well defined existing CPU instead of creating my own from scratch.

If you want a "true 16-bit design" it means the memory is addressed in 16-bit words, if you have a von neuman architecture (program and data memory are merged), it means all your opcodes are going to be 16-bit, and arguments a multiple of 16 bits. If that's not the case you'll have to cheat and read more than what you use, that will be perfectly possible but will significantly complicate a potential hardware implementation !

Finally I think if you have a 16-bit address space (that'd be 128k of memory, if you use 16-bit words), that's not a lot of memory, so wasting the high byte when in 8-bit mode might eat up significant memory... In that case I see no reason to use the 8-bit modes at all, saving memory would have been the SOLE use of this mode.

Also think if your but is rather to simplify the implementation of the processor (in emulation or HW), or simplify coding this processor in assembly. RISCs went the route to simplify the implementation, at the price of having more instructions to perform the same task, and having it being a nightmare to code for in assembly. But in the end it makes fewer difference when you code in a high level language, and it made it easier for compiler to target RISCs, as they could separate the instruction selection and register allocation process, something which is not the case on a 6502 family CPU.
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 »

Thank you Bregalad. You've convinced me that the address-bus should be based on 16-bit words.

The main purpose of the 8-bit mode was not primarily to save space, but rather to provide an 8-bit data type, which has uses for things like strings, and 8-bit color mode. I remember a quirk of the GBA's architecture being that the VRAM data bus was 16-bit wide only, so writing a single 8-bit value (for the 8-bit palette pixel-based mode, as an example), would require:

1. reading a 16-bit word from VRAM to cpu memory.
2. masking that data
3. shifting the new byte as necessary
4. oring in the new byte
5. writing the modified 16-bit word to VRAM.

TL;DR: I'm hesitant to give up the capability of using a 8-bit data type.
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 remember a quirk of the GBA's architecture being that the VRAM data bus was 16-bit wide only, so writing a single 8-bit value (for the 8-bit palette pixel-based mode, as an example), would require:
You might also be thinking of the strb/swpb hack used for slot-2 RAM expansion on the NDS for dslinux.
TL;DR: I'm hesitant to give up the capability of using a 8-bit data type.
ARM (and I think most other RISC ISAs) provide RMW instructions to handle data types smaller than the native word size.
tomaitheous
Posts: 592
Joined: Thu Aug 28, 2008 1:17 am
Contact:

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

Post by tomaitheous »

Movax12 wrote:
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

I while I haven't used ($zp,x) addressing mode yet, I could think of some optimizations or easier designed code, to make use of it. Unless it's a tight loop and you need crunch cycles, ZP should be reserved for other optimizations or just a large array of vectors (address registers). If you really need speed, use self modifying code - or 'code lists' (if you got the memory for it).


I don't use (zp,x) simply because I can't index after the indirection (which I'm almost always doing or optimizing for). An addressing mode like (zp,x),y would be more useful than without the Y indexing IMO.

I like what Hudson soft did with the PC-Engine Arcade Card. It has a huge 2megabyte additional ram to the system (which the cpu is 65x based), but instead of making it random access, they gave you 4 different ports to access it with. The ports replicate new address registers, which are 24bit wide, and have additional registers to go along with each of them; 16bit offset reg (indexing. can be unsigned or signed and auto inc/dec on read/write), 16bit 'window' reg ( and you can have this added to the main address reg by a special triggered port write. You can have the index reg previously mention, increment this instead of the main reg too). And other fancy stuff like byte or word indexing (whether the port inc/dec's on a byte or word read/write).
__________________________
http://pcedev.wordpress.com
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 »

ARM (and I think most other RISC ISAs) provide RMW instructions to handle data types smaller than the native word size.
Sorry but not quite. ARM provides 8-bit and, more recently, 16-bit support only for individual load and store instructions. Everything else is always 32-bit. The memory is addressed in 8-bit quantities (so it's not a "real" 32-bit architecture in the pure sense of it), but any reads or writes of 32-bit quantities are required to be aligned on words (else the results are unpredictable). More recently 16-bit reads/writes were implemented (I think it began at the ARM7 family), and then it's the same, it needs to be halfword aligned.

This was made so it's typically possible to intermix 32, 16 and 8 bit memories and memory mapped IO on the same bus. You simply drop the lower address bits when addressing a 16 or 32 bit memory. This however requires a bus controller that will convert access to a memory of a different size. I'm not familiar with exactly how that GBA VRAM issue came from, but it's probably exactly this : They lack a bus controller that converts reads and writes of different sizes.

In order to avoid all this mess, I'd strongly recommend to strictly restrict all your but to a single size, the 65c816 choosed 8-bit as it's single size and internally splits all 16-bit access into 2 8-bit access (I think, please correct me if I'm wrong), but if you're going for a "true" 16-bit CPU I'd recommend not ever dealing with 8-bit accesses in the 1st place. You won't get issues like the GBA does, as you won't be able to do a 8-bit access.
The only inconvenient is that it's a bit complicated to have an array of 8-bit values, but you'll just need a few opcodes to shift, and AND/OR the values with constants in order to get the individual values. You could even have instructions solely for this, i.e. "get high byte of" (i.e. read and shift right by 8 positions) and "get low byte of" (i.e. read and AND with $00ff). That's probably the way to go I'd say, much simpler to implement than a dual 8 and 16-bit mode for everything.
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 »

My latest iteration of addressing modes is as follows (restricted to seven now - I'm running out of bits in my opcodes!)

Code: Select all

==============================[ Addressing Modes ]==============================
Addressing Mode     Syntax       Value is...
Immediate           $1234        Value of Next Word
Absolute            [$1234]      Mem[Immediate]
Register            R            Value of Register
Indirect            [R]          Mem[R]
Indirect Indexed    [R,R]        Mem[R+R]
Indirect Post-inc   [R+]         Mem[R], R is post-incremented.
Indirect Pre-dec    [-R]         Mem[R], R is pre-decremented.
When thinking about the stack, I realized that in order to have the stack grow downwards, I would have to implement two more addressing modes - the opposites of the Post-increment and Pre-decrement indirects. Do I have this correct?

Code: Select all

The stack pointer is the address of the first available stack space. It is
decremented after a stack value is pushed onto the stack, and is incremented
before a stack value is popped from the stack. Thus the stack grows downward
from its initial address.
	Stack push is internally implemented as: [SP--] = Rx
	Stack pop is internally implemented as: Rx = [++SP]
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 »

As I explained on NESdev BBS back in 2004, there are two ABIs for stack handling: an empty stack and a full stack. Using store Rn, [--sp] for push and load Rn, [sp++] for pop produces a full descending stack.

As for opcode bits, are you applying addressing modes to ALU instructions or only to load and store? If you apply them only to load and store, you can reuse the add instruction's circuitry for your address generator.

I think a constant offset from a register is more useful than Absolute, especially for accessing elements of C structs or accessing local variables allocated on the stack. Absolute is really just good for reading or writing memory-mapped I/O, or reading or writing global variables (which have fallen out of fashion among programmers).
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 »

Thanks Tepples. I assume I'll have to initialize the stack to (stack bottom+1) --- so if I want the stack to start at 0x1FF, the stack must be initialized at 0x0200?
As for opcode bits, are you applying addressing modes to ALU instructions or only to load and store? If you apply them only to load and store, you can reuse the add instruction's circuitry for your address generator.
I currently use them for load, store, and all math operations. I like the symmetry... but I think I see what you're getting at.
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 »

Okay, I have a basic outline of the CPU. I appreciate all the suggestions that have been offered thus far - and I'd welcome any comments or suggestions on this outline!

My goal with this CPU was to have the functionality of each opcode (and the opcode, if possible!) defined in the bottom 8-bits of the opcode, to speed up decoding them in an emulator.

Eventually, I want to add memory paging, interrupts, and a supervisor mode - but I'm not sure how I would implement those - so the specification talks vaguely about these functions, but doesn't actually spell out how they are implemented in any detail.

Code: Select all

See first post in this thread
Last edited by pops on Sat Mar 08, 2014 1:10 pm, edited 1 time in total.
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 »

The ZCPU is a 16-bit processor
ZCPU might be confused with IBM or Infocom ISAs.
These registers [r0-r6 or A-C, I-J, and X-Y] are interchangable
(tepples waits for how subroutine calls work)
R = R * M (signed)
Signed and unsigned multiplication are the same operation for 16x16=16. They differ only for 16x16=32.
R = R % M (modulus, signed)
What are 5 % -3, -5 % 3, and -5 % -3 in this ISA?

I didn't see a description of what JSR, SWI, RTS, and RTI actually do, nor what registers a subroutine can expect to preserve.
Joe
Posts: 469
Joined: Mon Apr 01, 2013 11:17 pm

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

Post by Joe »

tepples wrote:nor what registers a subroutine can expect to preserve
That kind of information belongs in the specification for the ABI, not the CPU. On MIPS, there are at least five different ABIs defined, and I'm pretty sure they each define a different set of saved registers. I'm not saying that there shouldn't be an ABI specification, just that it should be reasonably separate from the CPU specification.

If the CPU is capable of memory paging, you could give it the ability to access more memory than it could normally address in 16 bits. Intel calls it "Physical Address Extension".
Post Reply