signed/unsigned

Hi there,

I’ve finally started with creating an M68000 emulator. This is a 32bit processor in many aspects and I want to use integeres for the registers (which are 32 bit).
Now here’s the trouble; we don’t have any unsigned datatypes in java (except for char) and Sun says it’s not necessary to have them. (which sucks btw)
So, say the PC points to memory address 0xffffffff (memory is an array), how would I do that?

Obviously, doing something like


byte fetched = memory[PC];

would get me an ArrayOutOfBoundsException since PC is 0xffffffff, which is -1.
I don’t want to revert to long because I feel that should not be necessary. Any thoughts?

Just thinking out loud here…


byte[] lowermem = new byte[0x7FFFFFFF];
byte[] highmem = new byte[0x7FFFFFFF];

...

if((memloc & 0x80000000) > 0) highmem[(memloc & 0x7FFFFFFF)] = databyte;
else lowermem[memloc] = memloc;

I think that’ll do it. Obviously you wouldn’t want to allocate 4 gigs of memory, so replace that with what mem sizes you’re actually using. :slight_smile:

[quote] think that’ll do it. Obviously you wouldn’t want to allocate 4 gigs of memory, so replace that with what mem sizes you’re actually using.
[/quote]
Thanks, although that was the kind of thing I wanted to avoid :slight_smile:
It’s all hypothetical anyway for now since the 68K addressing space is 24bit, but maybe later I will have a problem.

Actually it’s unnecessary to have them. You just need a unsigned multiplication/division and some unsigned comparissons.
Java lacks them as well.
[source]
int[] someArray;

read(int c1){
int temp = someArray[c1>>>2];
return (byte) ((temp>>>((c1%4)*8))&0xff);
}
Would it work? Who knows. Would it be faster than:
switch(c1%4){
someCode…
}
[/source]

You will never REALLY have a 4gig array will you?

And how about the more general problem of dealing with memory at discontinuous addresses. E.g. one ROM for sound data at 0xF0000000, one for graphics data at 0xE0000000, and the code at 0x10000000 just for kicks?

Also imagine emulating a Windows machine, where all protected kernel addresses are >0x80000000, even though you may only have 256MB of RAM.

I don’t think there is any getting around the fact that you need an address translation function, and that solves the original problem.

You’re right and this is just a bad example of my issues with java types.
The original problem is not addressing that much memory, the original problem is the lack of unsigned types and generally all inconveniences dealing with byte and bits in java.

When dealing with bits and bytes, you are forced to continuously cast back and forth between byte and int (with all performance implications), which makes java IMO a bad choice for this kind of thing.

With emulating 8bit machines, the example makes perfect sense though.
I have 3 options for the PC (Program Counter) or other 16 bit registers:

  • Use an int. I have to keep masking them by doing an &0xffff to prevent them from going out of scope. Yuck.
  • Use short. I can’t use it anymore for addressing since it can become negative for high memory.
  • Use char. Possible (= the only unsigned type in java), but if I do one logical operation it gets cast to an int and I have to cast it back again. Yuck.

You are correct that Java is not suited to bit twiddling. But one would hope that after JIT compiling the casts cost nothing because the compiler can see that simply using an instruction that processes the data as unsigned gives the correct result.

No argument that it is a significant pain when you need to write the Java code though.