32016 emulator on a 64 bit host??? [SOLVED]

discuss emulators of 26-bit acorn systems e.g. arculator and rpcemu
Post Reply
gtoal
Posts: 89
Joined: Sat Nov 04, 2017 2:07 am
Contact:

32016 emulator on a 64 bit host??? [SOLVED]

Post by gtoal »

In another thread ( viewtopic.php?f=16&t=25223&p=366509 ) I've reported how I was able to take the 32016 emulator code from https://github.com/hoglet67/PiTubeClien ... 16/32016.c and an embedded binary of Bas32 and build a working bas32 that runs on my x86 Linux system. My linux allows 64 bit "long long"" integers but it uses 32 bit addresses.

Unfortunately when I went to another Linux system which, significantly, has 64 bit addresses, the emulation broke completely.

It looks like the code uses its 'genaddr' array to pun on ns32016 addresses (which are really just indexes into the memory array that represents the 32016 memory) and the addresses of actual variables in the local program, such as the local copy of the 32016 registers.

Unfortunately this falls apart when the local addresses have to be 64 bit.

Looking around I see some other versions of this emulator which have separate genaddr and genreg arrays rather than using genaddr for both purposes. Is this a fix for the problem I'm seeing?

Any advice on which of these 32016 emulators is the best one to build on?:


in the 'no genreg' camp:

Code: Select all

https://github.com/hoglet67/PiTubeClient/blob/master/NS32016/32016.c <---
// B-em v2.2 by Tom Walker
// 32016 parasite processor emulation (not working yet)
// And Simon R. Ellwood

https://github.com/hoglet67/PiTubeDirect/blob/cobra-dev/src/NS32016/32016.c
// B-em v2.2 by Tom Walker
// 32016 parasite processor emulation (not working yet)
// And Simon R. Ellwood

https://github.com/neozeed/emul32k/blob/main/32016.c
// B-em v2.2 by Tom Walker
// 32016 parasite processor emulation (not working yet)
// And Simon R. Ellwood
and:
	http://cpu-ns32k.net/files/emul32k.zip (from http://cpu-ns32k.net/Emulator.html from
	https://virtuallyfun.com/wordpress/2017/09/09/definicon-dsi-32-co-processor-emulation/ )
	
https://github.com/fesh0r/b-em/blob/master/src/32016.c
/*B-em v2.2 by Tom Walker
  32016 parasite processor emulation (not working yet)*/

http://b-em.bbcmicro.com/B-emv2.2Linux.tar.gz
/*B-em v2.2 by Tom Walker
  32016 parasite processor emulation (not working yet)*/
in the 'genreg' camp:

Code: Select all

https://github.com/hoglet67/PiTubeDirect/blob/master/src/NS32016/32016.c
// B-em v2.2 by Tom Walker
// 32016 parasite processor emulation (not working yet)
// And Simon R. Ellwood

https://github.com/kilograham/b-em/blob/pico/src/NS32016/32016.c
// B-em v2.2 by Tom Walker
// 32016 parasite processor emulation (not working yet)
// And Simon R. Ellwood

https://github.com/stardot/b-em/blob/master/src/NS32016/32016.c
// B-em v2.2 by Tom Walker
// 32016 parasite processor emulation (not working yet)
// And Simon R. Ellwood
If the authors or any of the folks who have worked on this code are around, got any comments/advice for building on a 64 bit host?

Thanks,

Graham


PS Below are what I believe to be the problem areas in the copy I'm working from. I've marked the lines that gcc complained about when trying to compile on the 64 bit host.

Code: Select all

  uint32_t reg_addr = genaddr[1] + ((Regs[1].Whole & 1) ? -4 : 4);
        *(uint8_t *)(reg_addr) = temp; /* int-to-pointer-cast */
        *(uint16_t *)(reg_addr) = temp; /* int-to-pointer-cast */
        *(uint32_t *)(reg_addr) = temp; /* int-to-pointer-cast */
uint32_t genaddr[2];
          return read_x8(genaddr[c]);
          return read_x16(genaddr[c]);
          return read_x32(genaddr[c]);
      Temp = *(uint32_t *)genaddr[c]; /* int-to-pointer-cast */
      return Truncate(genaddr[c], OpSize.Op[c]);
      Temp = read_x64(genaddr[c]);
      Temp = *(uint64_t *)genaddr[c];
    return *(uint32_t *)genaddr[c];
  return genaddr[c];
          genaddr[c] = (uint32_t)&r[gen.OpType]; /* int-to-pointer-cast */
          genaddr[c] = (uint32_t)&FR.fr32[IndexLKUP[gen.OpType]]; /* int-to-pointer-cast */
          genaddr[c] = (uint32_t)&FR.fr64[gen.OpType]; /* int-to-pointer-cast */
          genaddr[c] = temp3.u8;
          genaddr[c] = temp3.u16;
          genaddr[c] = temp3.u32;
      genaddr[c] = r[gen.Whole & 7] + GetDisplacement(&pc);
        genaddr[c] += Offset;
        genaddr[c] = *((uint32_t *)genaddr[c]) + Offset; /* int-to-pointer-cast */
        genaddr[c] = read_x32(fp + temp);
        genaddr[c] += temp2;
        genaddr[c] = read_x32(GET_SP() + temp);
        genaddr[c] += temp2;
        genaddr[c] = read_x32(sb + temp);
        genaddr[c] += temp2;
        genaddr[c] = GetDisplacement(&pc);
        genaddr[c] = temp2 + GetDisplacement(&pc);
        genaddr[c] = GET_SP();
        genaddr[c] = GetDisplacement(&pc) + fp;
        genaddr[c] = GetDisplacement(&pc) + GET_SP();
        genaddr[c] = GetDisplacement(&pc) + sb;
        genaddr[c] = GetDisplacement(&pc) + startpc;
  uint32_t reg_addr = genaddr[1] + ((Regs[1].Whole & 1) ? -4 : 4);
        write_x8(genaddr[1] + 4, temp);
        write_x16(genaddr[1] + 4, temp);
        write_x32(genaddr[1] + 4, temp);
    genaddr[1] += OffsetDiv8(Offset);
          genaddr[0] += OffsetDiv8(Offset);
          genaddr[1] += OffsetDiv8(Offset);
          genaddr[1] += OffsetDiv8(Offset);
              write_x8(genaddr[WriteIndex], temp);
              write_x16(genaddr[WriteIndex], temp);
              write_x32(genaddr[WriteIndex], temp);
              write_x64(genaddr[WriteIndex], temp64.u64);
              *((uint8_t *)genaddr[WriteIndex]) = temp; /* int-to-pointer-cast */
              *((uint16_t *)genaddr[WriteIndex]) = temp; /* int-to-pointer-cast */
              *((uint32_t *)genaddr[WriteIndex]) = temp; /* int-to-pointer-cast */
              *((uint64_t *)genaddr[WriteIndex]) = temp64.u64; /* int-to-pointer-cast */
Last edited by gtoal on Tue Aug 09, 2022 4:20 pm, edited 1 time in total.
User avatar
hoglet
Posts: 12666
Joined: Sat Oct 13, 2012 7:21 pm
Location: Bristol
Contact:

Re: 32016 emulator on a 64 bit host???

Post by hoglet »

The most recent development of this code base has happened in PiTubeDirect, and the latest code is in the indigo-dev branch:
https://github.com/hoglet67/PiTubeDirec ... rc/NS32016

So that would probably be the best starting point.

It doesn't surprise me there are issues with 64-bit pointers.

We would like to run a future version of PiTubeDirect on ARM64, so I would be interested to see these issues tracked down and resolved.

I fear that might not be straightforward though, due to the inherrent complexity of the NS32K.

Dave
gtoal
Posts: 89
Joined: Sat Nov 04, 2017 2:07 am
Contact:

Re: 32016 emulator on a 64 bit host???

Post by gtoal »

Thanks. I'll see what I can do.

Issues with hosting on a 64 bit system should be entirely independent of the details of the 16032 architecture - I don't think that'll be a factor in ensuring the emulator is portable.

While I'm checking the 64bit issues, I'll have a quick scan for potential endian issues too. Its hard to find a big-endian host to test on nowadays but I'm trying to get one to check another project and if I do I'll check this out too.

G
User avatar
SKS1
Posts: 327
Joined: Sat Sep 19, 2020 12:04 am
Location: Highland Perthshire
Contact:

Re: 32016 emulator on a 64 bit host???

Post by SKS1 »

I can offer you a Sparc Ultra 5 ;-)
Miserable old curmudgeon who still likes a bit of an ARM wrestle now and then. Pi 4, 3, ARMX6, SA Risc PC, A540, A440
User avatar
hoglet
Posts: 12666
Joined: Sat Oct 13, 2012 7:21 pm
Location: Bristol
Contact:

Re: 32016 emulator on a 64 bit host???

Post by hoglet »

gtoal wrote: Sun Aug 07, 2022 10:10 am Thanks. I'll see what I can do.

Issues with hosting on a 64 bit system should be entirely independent of the details of the 16032 architecture - I don't think that'll be a factor in ensuring the emulator is portable.

While I'm checking the 64bit issues, I'll have a quick scan for potential endian issues too. Its hard to find a big-endian host to test on nowadays but I'm trying to get one to check another project and if I do I'll check this out too.
Looks like you started from a quite old version of the 32016 code base.

I've just tried the 32016.c code from the hognose-dev branch of PiTubeDirect and that does seem to work with 64 bit pointers:

Code: Select all

$ gcc bas32.c 32016.c Decode.c mem32016.c Trap.c -lm -obas32
$  ./bas32 
sizeof(void *) = 8
BBC Basic IV for 32000 (c) Acorn 1986
>PRINT PI
3.14159265
>10 FOR A=1 TO 10
>20 PRINT A
>30 NEXT
>RUN
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
>
It would be nice to place all of your fakeSVC additions in a seperate source file, to reduce the changes needed to 32016.c.

Sorry, it's been such a long to time since I worked on this, that I've completely forgotton that we had resolved the 64 bit issues in the original code base. That was needed to be able to re-use the code in b-em, which supports both 32 and 64 bit builds.

Dave
Last edited by hoglet on Sun Aug 07, 2022 12:51 pm, edited 1 time in total.
User avatar
hoglet
Posts: 12666
Joined: Sat Oct 13, 2012 7:21 pm
Location: Bristol
Contact:

Re: 32016 emulator on a 64 bit host???

Post by hoglet »

For reference, this was the commit (6 years ago) that brought in the 64-bit fixes:
https://github.com/hoglet67/PiTubeDirec ... bacf1caaf8

These were done by Steve initially in the b-em code base, then back-ported to PiTubeDirect.

Dave
User avatar
hoglet
Posts: 12666
Joined: Sat Oct 13, 2012 7:21 pm
Location: Bristol
Contact:

Re: 32016 emulator on a 64 bit host???

Post by hoglet »

Building for 32 bits I get this:

Code: Select all

$ gcc -m32 -O3 -Wall bas32.c 32016.c Decode.c mem32016.c Trap.c -lm -obas32
$ ./bas32
sizeof(void *) = 4
BBC Basic IV for 32000 (c) Acorn 1986
...
<Paste in CLOCKSP Basic>
...
>RUN
BBC BASIC CPU Timing Program
Real REPEAT loop       128.07MHz
Variant REPEAT loop    127.67MHz
Integer REPEAT loop    117.73MHz
Real FOR loop          126.55MHz
Variant FOR loop       126.23MHz
Integer FOR loop       126.63MHz
Trig/Log test          500.72MHz
String manipulation    171.98MHz
Procedure call         126.65MHz
GOSUB call             118.88MHz
Unweighted Average     167.11MHz

Compared to a 2.00MHz BBC B
Building for 64-bits I get this:

Code: Select all

$ gcc -m64 -O3 -Wall bas32.c 32016.c Decode.c mem32016.c Trap.c -lm -obas32
$ ./bas32
sizeof(void *) = 8
BBC Basic IV for 32000 (c) Acorn 1986
...
<Paste in CLOCKSP Basic>
...
>RUN
BBC BASIC CPU Timing Program
Real REPEAT loop       155.55MHz
Variant REPEAT loop    155.55MHz
Integer REPEAT loop    146.62MHz
Real FOR loop          153.15MHz
Variant FOR loop       153.61MHz
Integer FOR loop       165.68MHz
Trig/Log test          612.50MHz
String manipulation    217.81MHz
Procedure call         160.27MHz
GOSUB call             146.55MHz
Unweighted Average     206.72MHz

Compared to a 2.00MHz BBC B
So there's about a 25% speed improvement with 64-bits.

Dave
gtoal
Posts: 89
Joined: Sat Nov 04, 2017 2:07 am
Contact:

Re: 32016 emulator on a 64 bit host???

Post by gtoal »

> It would be nice to place all of your fakeSVC additions in a seperate source file, to reduce the changes needed to 32016.c.

Of course! That was just a quick hack to see if it was plausible. I'll structure it better when I apply the same fixes. (You didn't put that updated source online anywhere by any chance?)

Great to see that it works. Thanks!

G
gtoal
Posts: 89
Joined: Sat Nov 04, 2017 2:07 am
Contact:

Re: 32016 emulator on a 64 bit host???

Post by gtoal »

> I can offer you a Sparc Ultra 5

Heh, you'd get a shock if I took that as a serious offer :-) (Postage to Texas is a bit excessive).

Now you mention the Sparc, though, I forgot I have a Pizzabox in my shed. Wonder if it still works. I've never run it up over here.

I was actually thinking of using a Pi with BSD Unix - I'm fairly sure there's at least one version of BSD that runs the Pi in big-endian mode.

By the way, it turns out this is not the first time the 32016.c code has been used in this way - user 'Neozeed' did something similar for a non-Acorn add-on processor for the PC some years ago: https://virtuallyfun.com/wordpress/2017 ... emulation/ (I wasn't aware of the DSI board until I found that last night).

I've found the source of the Panos loader (in modula2) ready for the next stage - I did try converting it to C automatically (with a Modula2 to C transpiler) but there were too many modula2 definition files missing to allow the converter to work, so it looks like it'll have to be done the old fashioned way (i.e. by hand). Or I might just try running Panos with the emulated SVC interface and see if that's an easier route to loading rif files. Depends how many critical SVCs need to be implemented to allow Panos to run enough to allow loading.

G
Last edited by gtoal on Mon Aug 08, 2022 7:22 am, edited 1 time in total.
gtoal
Posts: 89
Joined: Sat Nov 04, 2017 2:07 am
Contact:

Re: 32016 emulator on a 64 bit host???

Post by gtoal »

I've made an attempt to recode this more cleanly as requested, so it can be merged with the original (which is now https://github.com/hoglet67/PiTubeDirec ... gnose-dev/ )

Unfortunately I broke something and haven't been able to find it. I was hoping Dave would have a look at this version and see what stupid thing I missed - my suspicion is the problem comes from my lack of understanding of the various ifdef'd options. Start from a clean fetch of https://github.com/hoglet67/PiTubeDirec ... gnose-dev/ and apply the patch in https://gtoal.com/acorn/pandora-emulati ... patch.diff and add the new .c and .h files from https://gtoal.com/acorn/pandora-emulati ... d_attempt/
(There's a README.txt in there too for what it's worth.)

Thanks,

Graham
User avatar
hoglet
Posts: 12666
Joined: Sat Oct 13, 2012 7:21 pm
Location: Bristol
Contact:

Re: 32016 emulator on a 64 bit host???

Post by hoglet »

gtoal wrote: Mon Aug 08, 2022 7:10 am Unfortunately I broke something and haven't been able to find it. I was hoping Dave would have a look at this version and see what stupid thing I missed - my suspicion is the problem comes from my lack of understanding of the various ifdef'd options.
I took a quick look, and the problem is how you are setting the RAM size, and where you are placing the stack.

Normally the stack pointer is initialized by Pandora, based on the results of a memory test. But you aren't running Pandora, so need an alternative mechanism, which you have in bas32.c. So far so good, but...

It looks like you are trying to force the RAM size to 16MB by defining a new local (static) RAM_SIZE variable in bas32.c. That's not going to work, you'll just end up with two independant RAM_SIZE variables, each with a different local file scope.

init_ram() sets the RAM size from a global variable called copro_memory_size (sorry this is horrible, it's just never been cleaned up). In your case, that variable (defined in bas32.c) is being set to 0, so init_ram() chooses the default size of 1MB. This results in your stack being placed in read-only-memory (above mem32016::RAM_SIZE). It fails at the first RET.

(16MB is actually slightly too big anyway, because normally the Pandora ROM and Tube registers are mapped at 0xF00000-0xFFFFFF, so init_ram() limits the RAM size to 15MB)

Fixing this is straightforward:

1. Get rid of the RAM_SIZE variable in bas32, as it's just confusing things to have two seperate copies of this variable.

2. Set copro_memory_size=15MB before calling ns32016_init(), which in turn calls ram_init().

3. Set the stacks to copro_memory_size-0x1000 and copro_memory_size-0x5000.

Also, I don't think I would bother trying to re-use/share copro-32016.c; it's cleaner to have your own bas32.c and make this as minimal as possible.

After a bit if fiddling, I ended up with:

Code: Select all

/*
 * Basic32 Emulation
 *
 * (c) 2022 Graham Toal
 *
 * This is basically ../copro-32016.c but it's simpler to have a separate copy here
 * To compile: cc -g -o bas32 -DBAS32 -I.. bas32.c 32016.c Decode.c mem32016.c Pandora.c -lm
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include "NS32016/32016.h"
#include "NS32016/mem32016.h"
#include "bas32.h"

// copro_memory_size is used by mem32016::ram_init(), max is 15MB
unsigned int copro_memory_size = 15 * 1024 * 1024;
int          tubecycles = 0;
uint32_t     TrapFlags = 0;
int          tube_irq = 0;

void n32016_dumpregs(const char* pMessage) { }
void tube_ack_nmi(void) { }
void HandleTrap(void) { }

int main(int argc, char **argv) {
   // initize the 32016 memory system
   n32016_init();
   // copy the Bas32 code
   for (int pos = 0; pos < sizeof(bas32); pos++) {
      write_x8(BAS32_BASE + pos, bas32[pos]);
   }
   // Preload and start in BAS32
   n32016_reset_addr(BAS32_ENTRYPT);
   // Manually initialize the stack (normally done in Pandora)
   S_FLAG = 1; STACK_P = copro_memory_size - 0x1000; // Supervisor stack
   S_FLAG = 0; STACK_P = copro_memory_size - 0x5000; // User stack
   // Run forever
   while (1) {
      tubecycles = 0x7FFFFFFF;
      n32016_exec();
   }
   return 0;
}

unsigned char bas32[] = {
...
};
Dave
gtoal
Posts: 89
Joined: Sat Nov 04, 2017 2:07 am
Contact:

Re: 32016 emulator on a 64 bit host???

Post by gtoal »

And that did the trick! - Wonderful, thank you! The explanation makes perfect sense.

Now we can get down to fleshing out the OS support and making it useful. Obviously file stuff is the first priority.

And I'll start looking at how to load rif files - whether it can be done with custom code and no Panos, or whether it needs Panos.

Although it would be preferable to have your master copy updated with the small changes needed to support the 4 new files, I'ld ask you to hold off on that for now as it *might* be necessary to so something similar to embed the Panos/Pandata images in the emulator too, and rather than have two sets of changes we should wait until we know if they're needed or not and do both at once in a more consistent way.

I've cleaned up https://gtoal.com/acorn/pandora-emulation/ and will freeze it at the current point until the next stage is done. (BigEd - you wanted to compile this - give it a try now. Details in the README.txt)

When there's any more to report I'll start a new thread in the 32 bit emulator forum.

Graham
Post Reply

Return to “32-bit acorn emulators”