Running binaries on a Communicator

bbc/electron apps, languages, utils, educational progs, demos + more
User avatar
arg
Posts: 1289
Joined: Tue Feb 16, 2021 2:07 pm
Location: Cambridge
Contact:

Re: Running binaries on a Communicator

Post by arg »

Summary of the rules for loadable *COMMANDs on Communicator:
  • Max size is 64K
  • Exec address must be set to &FFFFFFFE to signify a Communicator binary. Actual entry point is fixed as the first byte of the loaded file.
  • New code should be written to be position-independent, and the Load address set to &FFFFFFFF. Memory of suitable size will be allocated at an arbitrary location and the code loaded there.
  • When porting existing 6502 code, it can be tiresome to re-write it relocatable, but such code is naturally bank-independent as there was only one bank on 6502. So assemble it at any convenient address (preferably not in bank zero nor at offset zero in any other bank to avoid inadvertent assumptions), and set the Execute address to &FFFFnnnn where nnnn is the low 16 bits of the address it was assembled for. Space will be allocated at that offset in an arbitrary bank and the code loaded there.
  • The option of setting the Load address to some absolute value to force it to be loaded there is unlikely to be useful, as it will only succeed if that address is available within Task memory (which rules out most 'interesting' uses of it).
  • The code is entered with a JSL instruction, and should therefore return with a RTL. On exit, carry is clear for 'success', or carry set and BHA pointing to an error string (note that the string gets copied so that it continues to exist after the loaded program has been discarded, so pointing at a literal string in the program body is fine). Alternatively, the command can exit via BRK, but this is just an emergency measure: if the code uses BRK, it should set up its own BRK handler.
  • The code is entered in WORD mode. However, it's good practice to not assume that and explicitly set the desired 8/16 bit modes.
  • The code is called with &200 bytes of stack, and &100 of Direct Page. The first three bytes of DP point to the command tail. Note that this is a three-byte pointer so should be accessed with a LDALIY instruction - scope for bugs here using LDAIY by mistake which will work if the command string happens to be in the same bank as the program. Those three bytes can be overwritten afterwards or if the program doesn't care about command line parameters.
  • If the program needs more workspace than available in the DP/Stack allocations, it should allocate it via COP OPMM. Since there can only be one instance of the code running, it is also theoretically possible to use space within the code image itself as workspace; this is not recommended and has no obvious advantage for position-independent code, but might possibly be useful for converted 6502 code which wants workspace at a fixed absolute address.
(All of this assuming nothing changed between the printout I have and final release - but probably it didn't.)
User avatar
BeebMaster
Posts: 7379
Joined: Sun Aug 02, 2009 5:59 pm
Location: Lost in the BeebVault!
Contact:

Re: Running binaries on a Communicator

Post by BeebMaster »

This is very useful; does it suggest then that in order to get the existing 8-bit Econet library utilities working on the Communicator, without having to rebuild them or reverse engineer the code, all that is needed is to change the exec address to &FFFFFFFE and leave the load address alone?
Image
User avatar
dominicbeesley
Posts: 2210
Joined: Tue Apr 30, 2013 12:16 pm
Contact:

Re: Running binaries on a Communicator

Post by dominicbeesley »

Thanks Andrew,

Did you find this documented somewhere for 1.00 MOS or work it out from the sources? There looks to be the ability to set "bank independent" in the module type flags - is that used by the econet module or is it definitely position independent only - which is as you say tricky but not impossible to code for.

D
User avatar
arg
Posts: 1289
Joined: Tue Feb 16, 2021 2:07 pm
Location: Cambridge
Contact:

Re: Running binaries on a Communicator

Post by arg »

dominicbeesley wrote: Tue Feb 20, 2024 3:50 pm Did you find this documented somewhere for 1.00 MOS or work it out from the sources? There looks to be the ability to set "bank independent" in the module type flags - is that used by the econet module or is it definitely position independent only - which is as you say tricky but not impossible to code for.
Everything I wrote in the post immediately above I decoded from the source. Somewhere upthread it was mentioned that you had done some disassembly; I should probably compare that against my listing to see what has changed, but it's quite a big job. Better would be to find some way of scanning the listing, but I don't know how. I could mount a camera on a tripod and take photos as I flip over the pages of the fanfold paper, but I'm not sure what could then usefully be done with the resulting images.

The Econet primitives module was definitely position-independent by the time I finished with it; not certain if I finished doing the filing system, but it probably was (and you can tell immediately from the flags in the module header).

However, transient *COMMANDs which we are talking about here are not modules; per the above, you can make them position-independent or bank-independent.
BeebMaster wrote: Tue Feb 20, 2024 3:01 pm This is very useful; does it suggest then that in order to get the existing 8-bit Econet library utilities working on the Communicator, without having to rebuild them or reverse engineer the code, all that is needed is to change the exec address to &FFFFFFFE and leave the load address alone?
Not really, as they would only load if their existing load address happened to be available. And having loaded, the MOS interfaces that they use are probably no longer available.

Not that hard to convert if you have the source however (not sure which ones you are after, but I think I have source of everything distributed with the SJ fileservers).

I'm sure I did that work at the time, but alas all I took away at the end of the project was this one printout. By that stage of history, all my work was on Econet fileservers, and in this case it was Acorn's fileserver not mine.
RobC
Posts: 3816
Joined: Sat Sep 01, 2007 10:41 pm
Contact:

Re: Running binaries on a Communicator

Post by RobC »

arg wrote: Tue Feb 20, 2024 5:46 pm Not really, as they would only load if their existing load address happened to be available. And having loaded, the MOS interfaces that they use are probably no longer available.

Not that hard to convert if you have the source however (not sure which ones you are after, but I think I have source of everything distributed with the SJ fileservers).
I've disassembled most of the 6502 Econet utilities and have converted a number of them for use on the Communicator.

So, a big thank you for this as it's really useful. Next time I get my Communicator out I'll try setting the exec and load addresses to see if the utilities I've already converted will load and run.
User avatar
arg
Posts: 1289
Joined: Tue Feb 16, 2021 2:07 pm
Location: Cambridge
Contact:

Re: Running binaries on a Communicator

Post by arg »

dominicbeesley wrote: Sat Feb 17, 2024 12:25 pm Any hints at the thinking behind the internals would be a big help
While it was an interesting project, it was just a few intense months and after that I didn't touch a Communicator again, so it's difficult to recall things in enough detail to be useful.

But broadly, we'd inherited a crude port of the 6502 BBC MOS and were working to take advantage of the 816 extra features in various ways.

One aspect was making everything position-independent; it was perceived that with the new BRL/PEA/PEI/PER instructions, stack-relative address modes, more generous sized stack and more plentiful 'ZP', the cost of making code position independent was negligible. This wasn't an objective in itself, but made for more efficient management of the address space and in some sense replaces the 'sideways' ROM/RAM that allowed you to have multiple things loaded in the BBC address space without worrying about relocation.

Most of the objectives in terms of visible new functionality were about doing more things at once. With DP effectively giving you multiple 'zero page's and multiple stacks now available, this easily gave you multiple instances of any application - BBC code was already used to workspace being in indeterminate location (OSHWM/PAGE and HIGHMEM), so duplicating the ZP and the stack was all that was needed to go from a single application to multiple instances of it. Similarly (but less easily) BBC had a single current filing system, Communicator intended all filing systems to be active simultaneously and you could use pathnames with net:$.foo ram:$.foo etc. That also opened up the possibility to have a scheme of accessing device drivers through filesystem calls. I'm not sure which system inspired the device driver mechanisms: I'm sure I've seen this style of access (opening a serial port and giving baudrate etc as part of the 'pathname' that you open) in some other system, but I can't remember which. TRIPOS would be the obvious one given the people involved, but a quick glance doesn't seem to match up.

Lots of interfaces needed cleaning up - being either 16-bit when 24-bit was needed, or having single-instance assumptions, so a whole set of new interfaces were defined with the intention of having a consistent set of calling conventions (BHA pointing to a parameter block, X and Y for additional reason-codes or handles) and using COP rather than a table of callable entrypoints. I think the use of COP was with vague intentions of hiding more of the OS internals from the user, maybe with a thought to future protected-mode hardware (though there was not at the time any intention of Communicator OS concepts passing over to the ARM products; the fact that some eventually did was a much later idea when ARX was scrapped and Arthur/RiscOS initiated). Unfortunately, it appears that the budget ran out before the transition to new interfaces was complete, leaving the mixture in the OS as shipped and arguably nullifying the whole objective. The coroutine stuff had been done early as part of the cosmetic work to show off the machine running multiple things at once, hence the fact that it got a call-block interface rather than COP.

Modules then were the upgraded replacement for Sideways ROMs, and would be resident either in actual ROM or loaded to RAM (note however that the *COMMAND mechanism did NOT load a module, nor did *LOAD, there was some other way to achieve that). The facility to have BASIC programs in a module was a new innovation.

Note BTW that our/MASM's use of register names does not quite match WDC's documentation of the CPU. We call the two halves of the 16-bit accumulator H and A (cf. B and A), the data bank register B (vs DBR) and the program bank register K (vs PBR).
Pernod wrote: Sat Feb 17, 2024 8:36 pm Don't want to derail this topic too much, but do you have any idea what the PCF0335 device does in the Communicator? We haven't been able to find a datasheet for this part, so could be a custom thing. I think it's a I2C device and likely modem related, maybe dialler and baud rate generator for the ACIA 6850. Any clues would be really useful.
Unfortunately I have no direct knowledge.

However, it seems slightly surprising that there would have been a custom chip produced for the Communicator, which was mostly a shoestring-budget enterprise. Looking at what Dave has deduced, I'm wondering if the modem design was bought-in and that custom chip came with it. Or another thought is that the Communicator modem has a lot in common with the earlier BT Merlin M2105 expansion for the Electron (from photos, it appears to use the same modem chip and certainly the two products came from the same division, slightly isolated from the rest of Acorn). So maybe this custom chip sweeps up what was discrete logic in the M2105? And maybe it was shared with some other (non-Acorn) products? I don't believe that Acorn had any modem hardware expertise in-house.
User avatar
dominicbeesley
Posts: 2210
Joined: Tue Apr 30, 2013 12:16 pm
Contact:

Re: Running binaries on a Communicator

Post by dominicbeesley »

Thanks for all this Andrew, I wish I'd known you were so involved with the development of the Communicator - I'd have pestered you more when I was starting the disassembly. That's a really nice insight into how things were developed. I think I found what look like bits of left over MOS (from the Electron?) so I'm guessing that that was how the boards were first brought up. It wasn't clear from the documentation whether the far-call or COP mechanisms were the preferred method. My impression is that COP is neater but the far-call mechanism might be faster?

There are still load of things I don't understand in there so any scans or photos of the actual source would be great but I understand if you don't fancy undertaking such a huge task!

Are you open to more specific questions (feel free to say no!)

D
User avatar
arg
Posts: 1289
Joined: Tue Feb 16, 2021 2:07 pm
Location: Cambridge
Contact:

Re: Running binaries on a Communicator

Post by arg »

dominicbeesley wrote: Wed Feb 21, 2024 12:21 pm I think I found what look like bits of left over MOS (from the Electron?) so I'm guessing that that was how the boards were first brought up.
Very likely Electron MOS used as a starting point, to drive the video. As I noted in the source listing, the Econet stuff came from BBC ANFS.
It wasn't clear from the documentation whether the far-call or COP mechanisms were the preferred method. My impression is that COP is neater but the far-call mechanism might be faster?
I think neatness trumped minor efficiency, though the exact trade-off will depend on the call in question (as the COP method saves you a register compared to the call).
There are still load of things I don't understand in there so any scans or photos of the actual source would be great but I understand if you don't fancy undertaking such a huge task!
I'm definitely up for doing something, but I was hoping for a plan with a better risk/reward than laboriously taking loads of photos with no clear idea what would happen afterwards.
Are you open to more specific questions (feel free to say no!)
Ask away, though I may not know many answers. Unfortunately my main clear memories from the project are of completely unimportant things (I can, for example, tell you what Paul's password was on the fileserver - because the guys were trying to guess it one evening and I succeeded where they failed!).
User avatar
dominicbeesley
Posts: 2210
Joined: Tue Apr 30, 2013 12:16 pm
Contact:

Re: Running binaries on a Communicator

Post by dominicbeesley »

arg wrote: Wed Feb 21, 2024 6:41 pm I'm definitely up for doing something, but I was hoping for a plan with a better risk/reward than laboriously taking loads of photos with no clear idea what would happen afterwards.
I'm guessing there are a lot of pages, what sort of state are they in. Maybe if you take a couple of sample pictures and we could ask around for options - it has been a long time since I did any serious scanning/OCR'ing. I've no idea what's involved these days. I don't blame you if you don't want to get into all that. I don't recall it looking hugely entertaining!
arg wrote: Wed Feb 21, 2024 6:41 pm Ask away, though I may not know many answers. Unfortunately my main clear memories from the project are of completely unimportant things (I can, for example, tell you what Paul's password was on the fileserver - because the guys were trying to guess it one evening and I succeeded where they failed!).
One area I'm interested in is around the module referencing mechanism COP 27 and COP 29 - it looks like COP 27 makes a block in DP with some sort of entry shim code and then another return block with a pointer to that shim which COP 27 rearranges as another block which the calling module then PEI's onto the stack and RTL's into....There seems to be a lot of indirection going on. But maybe I'm missing something or completely misunderstanding what was going on!

Here are some points of interest in the disassembly: Another probably daft question
User avatar
BigEd
Posts: 6261
Joined: Sun Jan 24, 2010 10:24 am
Location: West Country
Contact:

Re: Running binaries on a Communicator

Post by BigEd »

arg wrote: Wed Feb 21, 2024 6:41 pm
dominicbeesley wrote: Wed Feb 21, 2024 12:21 pm There are still load of things I don't understand in there so any scans or photos of the actual source would be great but I understand if you don't fancy undertaking such a huge task!
I'm definitely up for doing something, but I was hoping for a plan with a better risk/reward than laboriously taking loads of photos with no clear idea what would happen afterwards.
Sharing a few photos might be a good start, because if OCR looks at all possible then that would be a good resource for future travellers. It's also possible to get a few people to contribute a re-typing by hand.

In this case I took some 550 photos, bundled them into a zip and the Internet Archive did all the post-processing including OCR. One photo had failed to autofocus so someone else provided a replacement to splice in. I think the whole thing took me a few evenings - and the files I left on the Archive are there for anyone, anytime. They could be post-processed to make them more readable, and the new versions uploaded. Of course a camera and tripod and flash with diffuser would have been better, but I used what I had, which was a handheld mobile phone and daylight, and a sheet of glass from a picture frame to help flatten the page.
RobC
Posts: 3816
Joined: Sat Sep 01, 2007 10:41 pm
Contact:

Re: Running binaries on a Communicator

Post by RobC »

Briefly had one of my Communicators out tonight in preparation for tomorrow's RISC OS South West Show so I tired setting the load and execution addresses as advised.

Lo and behold it works - only had time for a brief play but I got my Communicator versions of *PROT and *UNPROT running :D

Just need to do the same for the other Econet utilities now...
User avatar
dominicbeesley
Posts: 2210
Joined: Tue Apr 30, 2013 12:16 pm
Contact:

Re: Running binaries on a Communicator

Post by dominicbeesley »

Thanks for confirming Rob, I'll be trying that out when I get a chance...though I'm not sure how I get compiled programs into MAME! How did you transfer yours?

To answer some of my own slightly rambling non-question above, it looks like the palaver is slightly necessary. When entering a module we need to have not only its address but a way for the module to get its own workspace pointer. It seems when entering a module the client program pushes 6 bytes onto the stack with 3 pei's from the data returned by COP 27/29 this contains a pointer to the module in the first 3 bytes and a pointer to an rtl in the second 3. This seemed a bit wasteful until I realised that there isn't an easy way of either doing an indirect call via direct page or of pushing 3 bytes onto the stack (which is what is really needed). Pushing the extra pointer to do a harmless RTL and restore the stack. [ Is my reasoning correct there?]

The address that is pushed in the 1st 3 bytes points to a per-module reference block in bank 0 this contains a small shim program

Code: Select all

0:	phd
1:	jsl <address of module entry point>
5:	pld
6:	rts
7:	.byte <module reference count? >
8:	.word <module workspace pointer >
This sets up the entry conditions for the module and allows the module to find its workspace word by adding 4 to the return address of its entry point return value which will always be via the shim above.

The keyboard module disassembly contains this in action at service call entry:

Code: Select all

		pld				; pop my return address as the DP pointer
		phd				; restore stack
		pei	(DP_MOSREF+4) ; Get private workspace pointer into DP
		pld
The first pld/phd sequence makes the return address of the service call be the start of direct page (the return even though a long return will always be in bank 0), the pei then pushes workspace value on the stack and pops it as the direct page pointer for the module.

The module has to setup its own direct page which the keyboard module does in service call 2

Code: Select all

	phd
	pld
	bne	LFF7E87		; already allocated i.e. DP<>0
	cop	COP_10_OPADP	;allocate 17 bytes of DP
	.word $0017
	bcs	LFF7EA1
	rep	#$30
	pea	$0000
	plb
	plb				; bank = 0
	ldy	#$0004
	sta($05,S),y		;store allocated DP in private workspace pointer
	tcd				;switch to new DP
There may be better ways to reference something [I've not work out what though]. This however, is fairly neat. I'm not sure if this documented anywhere in the manuals though? I couldn't find anything the "modules" chapter of the "Communicator Systems Manual". It does require that module writers have knowledge of (and poke at) stuff on the stack/in bank 0 but handle modules at random addresses nicely!

D
RobC
Posts: 3816
Joined: Sat Sep 01, 2007 10:41 pm
Contact:

Re: Running binaries on a Communicator

Post by RobC »

dominicbeesley wrote: Mon Feb 26, 2024 2:22 pm Thanks for confirming Rob, I'll be trying that out when I get a chance...though I'm not sure how I get compiled programs into MAME! How did you transfer yours?
I have the Communicators connected to a PiBridge Econet Filestore so transferring files is easy - I've also got it connected to BeebEm on my laptop so can just paste code in and have it ready to compile on the Communicator.

This is also why I'm interested in getting the Econet utilities ported. I've got *PROT, *UNPROT, *LEX and *LCAT working so just need to move on to the more complicated ones now...
User avatar
dominicbeesley
Posts: 2210
Joined: Tue Apr 30, 2013 12:16 pm
Contact:

Re: Running binaries on a Communicator

Post by dominicbeesley »

I'm not clear whether the MAME emulation supports Econet, I will have to have a delve!
james
Posts: 330
Joined: Tue Aug 15, 2023 8:41 pm
Location: NE Hampshire
Contact:

Re: Running binaries on a Communicator

Post by james »

dominicbeesley wrote: Tue Feb 27, 2024 8:51 am I'm not clear whether the MAME emulation supports Econet
From https://www.stardot.org.uk/forums/viewt ... 70#p298070
econet: partially emulated, not working
But that was 3½ years ago …
User avatar
dominicbeesley
Posts: 2210
Joined: Tue Apr 30, 2013 12:16 pm
Contact:

Re: Running binaries on a Communicator

Post by dominicbeesley »

Thanks James,

I should have remembered - I was on that thread!

D
Post Reply

Return to “8-bit acorn software: other”