b-em PDP11 tube processor

discuss bbc micro and electron emulators (including mame) here!
Post Reply
Coeus
Posts: 3557
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

b-em PDP11 tube processor

Post by Coeus »

Cribbed from the PiTubeDirect project, I now have a branch of b-em with a PDP11 co-processor:
pdp.png
https://github.com/stardot/b-em/tree/sf/pdp11

I did come across a couple of interesting things along the way.

1. The routine loop0 in the PDP11 core (pdp11.c) would execute as long as tubeContinueRunning() returned true. For integration into b-em I had defined this as:

Code: Select all

static inline int tubeContinueRunning() {return tubecycles > 0;}
when I added the 6809. The 6809 also calls tubeUseCycles() which I had defined as:

Code: Select all

static inline void tubeUseCycles(int c) {tubecycles -= c;}
so together these would implement a scheme where the CPU runs for an allowed number of cycles and then lets something else to have a go. It doesn't look like the PDP11 makes any calls to tubeUseCycles, in fact it looks like it does do cycle accounting at all so instead I have hacked loop0 to use one cycle per instruction. This was necessary because if loop0 never returns the host 6502 never runs and therefore the PDP11 is stuck waiting for a tube register that never changes. So a question for hoglet mainly, is there a standard interface here between a core and the rest of PiTubeDirect?

2. The interrupt handling seems odd. The PDP11 core defines a routine pdp11_interrupt() so I had the tube ULA interrupt code call this when R4 was written to. This almost worked in that the first write to R4 for a host->parasite transfer generates the interrupt on the parasite side but then so did each subsequent write to R4, i.e. the transfer address etc. Looking more closely it seems some "glue code" in the PiTubeDirect copro-pdp11 is checking the PDP11's interrupt priority mask before calling pdp11_interrupt(). This is what seems a little strange - normally I would expect a processor to check it's own interrupt mask/priority before accepting an interrupt. Is this a drop off in the PDP11 core or is the PDP11 odd?

3. The PDP11 client ROM fails to defend against it's own data areas being overwritten by incoming data from the tube. This means it crashes with MOS 3.50 because this transfers a (useless to the PDP11) version of BASIC across that is being relocated to run in high memory (on the 6502) and therefore sits just below the ROM on the 6502 co-pro and on top of workspace on the PDP11. It works fine on MOS 3.20 and the non-master OSes.

On this last point I had a previous discussion with JGH. His view was that the host should be able to transfer to any address in the parasite but it seems to me this is not possible. If the host crashes the parasite by overwriting the workspace of the code that is receiving the transfer then the tranfer will fail just as surely as if the parasite had chosen to ignore the incoming data with the additional anoyance of crashing the parasite so having the client ROM check the incoming address and simply discard anything that would overwrite it seems like the best solution to me. If an OS want to replace the client ROM and use its own drivers for the tube hardware then it would need to transfer to a lower address initially and then relocate itself.
User avatar
jgharston
Posts: 5332
Joined: Thu Sep 24, 2009 12:22 pm
Location: Whitby/Sheffield
Contact:

Re: b-em PDP11 tube processor

Post by jgharston »

Coeus wrote: Fri Sep 13, 2019 2:26 am 3. The PDP11 client ROM fails to defend against it's own data areas being overwritten by incoming data from the tube. This means it crashes with MOS 3.50 because this transfers a (useless to the PDP11) version of BASIC across that is being relocated to run in high memory (on the 6502) and therefore sits just below the ROM on the 6502 co-pro and on top of workspace on the PDP11. It works fine on MOS 3.20 and the non-master OSes.
Same thing happens with the Z80 CoPro - the MOS 3.50 sends HiBasic across to B800-F800 trashing the Client code. There's nothing the Client can do to stop this. And if you want to be able to load over the Client, as with the CP/M BIOS, it's essential. Plus, that's the defined API, the host is allowed to fling whatever it wants to the client regardless of the effects on the client. It's annoying, but the solution to "my arm hurts when I do this" is "don't do it" not "chop your arm off".

The "correct" solution is for the host to examine the Client and determine that it is the correct target for what it wants to fling over, and refuse if it doesn't match. Unfortunately there's no API for this, but with Z80, 6809 and PDP11 BASIC* I worked out a close-enough workaround - read the byte at &FFF7 from the Client and only proceed if it is the correct 'JP' opcode for the CPU you are targetting. Not perfect as there's a slight chance of a false positive if the Client has a more than 64K of memory and &0000FFF7 just happens to contain the correct byte, eg an ARM CoPro where something has done ?&FFF7=&C3 would make it "look like" a Z80.

*Actually, generic code that can be used with any language ROM. link, source

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.45
(C) Copyright J.G.Harston 1989,2005-2024
>_
User avatar
jgharston
Posts: 5332
Joined: Thu Sep 24, 2009 12:22 pm
Location: Whitby/Sheffield
Contact:

Re: b-em PDP11 tube processor

Post by jgharston »

Coeus wrote: Fri Sep 13, 2019 2:26 am If the host crashes the parasite by overwriting the workspace of the code that is receiving the transfer then the tranfer will fail just as surely as if the parasite had chosen to ignore the incoming data with the additional anoyance of crashing the parasite so having the client ROM check the incoming address and simply discard anything that would overwrite it seems like the best solution to me.
Same thing happens on the 6502 if you load over &00F0-&00FF. The 6502 Client doesn't do anything to stop you the user trashing the system. The whole Acorn philosophy is that it is ***YOUR*** responsibility what **YOU** do to **YOUR** system.

As an eample, the Torch systems and the ETI 6809 systems reaaaalllyyy piss me off as they are implemented as "we, in our divine towers, shall only allow you to ask the host for this small handful of actions that *we* deem that you lowly plebs shall ever consider ever thinking of using". OSBYTE 128, yeah, we'll let you do that. Maybe. OSBYTE 128,7? No. OSWORD 163? Bugger off. OSFILE anything? Pah!, you're joking. The proper approach is the Acorn approach - here's the API, do with it as you will, the *HOST* determines if a action is appropriate or not, ***NOT***** the Client. The Client has no ability and no authority to chose to determine what a valid action is or is not. PLOT 240? Nah, I'm not going to let you do that because ***I**** think that PLOT 240 is not something you should never be allowed to use.

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.45
(C) Copyright J.G.Harston 1989,2005-2024
>_
User avatar
hoglet
Posts: 12679
Joined: Sat Oct 13, 2012 7:21 pm
Location: Bristol
Contact:

Re: b-em PDP11 tube processor

Post by hoglet »

Coeus wrote: Fri Sep 13, 2019 2:26 am So a question for hoglet mainly, is there a standard interface here between a core and the rest of PiTubeDirect?
There is, but it's at a much higher level:

Code: Select all

extern void copro_pdp11_emulator();
i.e. the wrapper class for each Co Pro is really the implementation of the standard one method API.

In PiTubeDirect, copro_pdp11_emulator() will run as the main program, only returning when another Co Pro is selected. The mechanism for this is a bit ugly, and involves looking for a change in a global variable (copro, which indicates the current co processor number).

The reason I did it this way was because I wanted to minimise the changes I had to make to each third-party CPU implementation, so it's less painful if a new verson of the third-party CPU implementation is released.
Coeus wrote: Fri Sep 13, 2019 2:26 am Looking more closely it seems some "glue code" in the PiTubeDirect copro-pdp11 is checking the PDP11's interrupt priority mask before calling pdp11_interrupt(). This is what seems a little strange - normally I would expect a processor to check it's own interrupt mask/priority before accepting an interrupt. Is this a drop off in the PDP11 core or is the PDP11 odd?
Again, I think it's done this way to minimise the changes I was making to third party code.

Some of the other Co Pro's use the same pattern (e.g. the 80x86)

Dave
Coeus
Posts: 3557
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: b-em PDP11 tube processor

Post by Coeus »

jgharston wrote: Fri Sep 13, 2019 11:50 am Same thing happens on the 6502 if you load over &00F0-&00FF. The 6502 Client doesn't do anything to stop you the user trashing the system. The whole Acorn philosophy is that it is ***YOUR*** responsibility what **YOU** do to **YOUR** system.
But the issue here is it is not me sat at the keyboard doing something silly to crash the system; it the the combination of OS and BASIC, as supplied by Acorn together in the 1Mbit ROM that are doing it. Without patching something the combination of MOS 3.5 and either Z80 or PDP11 is unusable as it will always crash immediately on boot before I get to type anything.

Yes, I agree that the host OS pushing over a completely useless language ROM is a defect in the tube start-up protocol. I'd even go as far as saying that the host probably shouldn't push anything at all and that, right from the start, the client processor should be requesting what it wants. That means a processor with a disc-based OS could go straight into requesting the boot file/sector etc. but hindsight is a wonderful thing.
Last edited by Coeus on Fri Sep 13, 2019 4:04 pm, edited 1 time in total.
Coeus
Posts: 3557
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: b-em PDP11 tube processor

Post by Coeus »

jgharston wrote: Fri Sep 13, 2019 11:43 am *Actually, generic code that can be used with any language ROM. link, source
Ok, having your PDP11 BASIC ROM loaded does seem to salvage the situation in that now PDP11 BASIC gets transferred instead and the PDP11 is quite happy to run that. That doesn't address the case where you are happy to drop into a simple command prompt in the client ROM to start some other OS. It also leaves me wondering how this language priority mechanism works.

Anyway, having got BASIC running, how fast should a PDP11 be? I currently get:
clocksp.png
I suspect that is probably a bit fast.
Last edited by Coeus on Fri Sep 13, 2019 4:40 pm, edited 2 times in total.
User avatar
dv8
Posts: 397
Joined: Mon Jun 22, 2009 10:07 pm
Contact:

Re: b-em PDP11 tube processor

Post by dv8 »

Coeus wrote: Fri Sep 13, 2019 4:39 pm That doesn't address the case where you are happy to drop into a simple command prompt in the client ROM to start some other OS.
You could use *CONFIGURE to set the default language to an empty slot or a service-only ROM, e.g. *CONF.LANG 13

Ctrl+Break will then give 'This is not a language' and drop to a supervisor prompt.
Last edited by dv8 on Fri Sep 13, 2019 6:24 pm, edited 1 time in total.
Coeus
Posts: 3557
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: b-em PDP11 tube processor

Post by Coeus »

Coeus wrote: Fri Sep 13, 2019 4:39 pmIt also leaves me wondering how this language priority mechanism works.
So it works by using a service call to retrospectively update the OSes cached ROM type byte to disable languages that are not for the correct processor.

That's quite clever.
Coeus
Posts: 3557
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: b-em PDP11 tube processor

Post by Coeus »

This PDP11 version of B-Em is now available as a release from GitHub with pre-built binaries for Windows.
See https://github.com/stardot/b-em/releases/tag/pdp11pre1
Coeus
Posts: 3557
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Re: b-em PDP11 tube processor

Post by Coeus »

jgharston wrote: Fri Sep 13, 2019 11:43 am *Actually, generic code that can be used with any language ROM. link, source
The first of these links is dead. While I see the relevance of the ROM header in that the type byte has been extended at some point to declare the CPU type the ROM is intended to run on, it doesn't address how to make the tube host actually look at this and byte &FFF7 on the client.

EDIT: I see that the ROM service code here isn't actually doing the language transfer but is altering the ROM table so the tube code does not transfer an unsuitable ROM. I note BASIC 3.32 does have a service entry but it looks pretty full to me. But, presumably, any service ROM could manipulate the OS ROM table any time before the tube host actually transfers the language.
Coeus
Posts: 3557
Joined: Mon Jul 25, 2016 12:05 pm
Contact:

Z80 Tube and MOS 3.50 (was Re: b-em PDP11 tube processor)

Post by Coeus »

It seems this is even more broken than I thought.

With the Z80, the BIOS seems to be too tightly integrated into the client ROM in the sense that it uses areas of the RAM copy of the client ROM for various reasons. In part this seem to stem from the fact that some of the code in the client ROM only needs to execute on reset and can then be discarded while some needs to stick around, for example tube transfer code and MOS API. It would have made much more sense for the client ROM to have had these two parts much more clearly divided, so there was a simple watermark of what could be overwritten and what should not be.

Pursuing the idea of manipulating the OS ROM table (at &02A1) to remove the language bit from any ROM that contains code for a different CPU than the current tube processor also causes a problem because, in the Z80 case, it is quite normal for there to be no ROMs with Z80 code in the slots in the I/O processor as the Z80 is expected to boot CP/M. However the tube host code does not seem to be able to cope with there being no suitable language to transfer and fails to send some acknowledgement that is part of the tube protocol, leaving the Z80 in a loop waiting.

So the bodge becomes even more complicated. It is necessary to first search to see if there is a suitable ROM and, if so, force the selection of that one then, if there isn't a suitable one, choose one that is unsuitable but at least doesn't relocate high and crash the parasite.

The whole thing is a dogs dinner!
Post Reply

Return to “8-bit acorn emulators”