Hi Brian,
I hope this isn't too waffly a reply; I can see a few ways you could choose to go with this so I've tried to sketch out various possibilities. Apologies if this comes across as either patronising or lacking in detail or both, it's not intended...
Just a general observation first: I am going to suggest that you look at some of the older versions in my repository in what follows. Please be aware, if you aren't already, that the VM is still evolving upstream - new opcodes get added and some opcodes get repurposed. So if you do decide to do something starting with an older version of my repository, you will either need to a) stick with the upstream PLASMA compiler from the same date or b) port the newer upstream changes into the older version from my repository.
I have made a few changes to the PLASMA compiler itself (toolsrc/*), but I don't think these are really related to the Acorn port - they're experimental optimisations which would be equally useful (or useless) for the Apple version. I've sent some of them upstream already, the ones which haven't been upstreamed I am still evaluating. So one immediate and fairly cheap win if you're after minimal divergence from upstream would be to switch to using the upstream version of the compiler (but from a suitable date, as noted above). On the other hand, barring bugs in my experimental optimisations, any code you write should work equally well with my compiler or the upstream version - they just aren't that different.
Moving on to the VM itself, I think it's useful to consider the assembly language part first (vmsrc/plvmbb*.s for my port, vmsrc/plvm01.s for the Apple I version, vmsrc/plvm02.s for the Apple II version). If I just look through a diff between plvm02.s and plvmbb.s, I think the main changes in my port are:
- Changes in the addresses of various ZP locations. I think this is mostly inevitable.
- Some new macros to check for things like stack underflow/overflow. These could be easily removed to reduce diverge from upstream.
- PLAS128 (the banked RAM support). Manually removing all the conditionally compiled code for the PLAS128 case would remove most/all of this divergence.
- A bit of code reordering to keep the VM size down. It would be a little bit tedious to undo this, but not particularly difficult.
- Some extra (and relatively self-contained) code to relocate the VM code automatically to PAGE to give as much free RAM as possible. This could easily be removed.
So that part really hasn't diverged all that much. It might therefore be worth you re-using this (perhaps with the changes suggested above, according to taste) for producing a minimal port.
The part of the VM written in PLASMA itself (vmsrc/bbcmd.pla for my port, vmsrc/a1cmd.pla for the Apple I version, vmsrc/a2cmd.pla for the Apple II version) - let's call this the "shell" for want of a better name - has certainly undergone a lot more modification in my port. I have tried to avoid making any changes which would cause avoidable source-code incompatibilities from upstream - i.e. I hope that a PLASMA program which doesn't use Apple-specific memory addresses or OS calls would compile and run unaltered on my port. I also tried to factor out new functionality like the 32-bit arithmetic library and some of the Acorn OS support into its own loadable modules, as you suggest (DWORD and ACORNOS, respectively).
Where I included Acorn-specific code in the core VM it was either because the core VM itself needed it anyway or because it was tied so closely to the core VM implementation that separating it out would be infeasible:
- The mode() command, for example, needs different code in the PLASMA and PLAS128 versions of the VM, which would get messy if it lived in a loadable module. (mode() is also exposed at the PLASMA prompt so in a very weak sense the core VM itself needs it, but I only added support at the prompt because it was cheap and felt a lot nicer - previously you had to change mode before starting the VM.)
- setjmp() and longjmp() were my solution to mapping Acorn OS errors (generated via BRK) into the PLASMA VM. Again, these are tied quite closely to the VM internals and differ between PLASMA and PLAS128.[There have been some similar functions added upstream recently which I need to consider as possible replacements; I am still porting the latest upstream code so I haven't got round to looking at this yet.]
I also made changes to the core VM which scratched my own itches in playing around with PLASMA, but which aren't really Acorn-specific:
- Checking for heap full and generating an error if this occurs
- Allowing the symbol table to grow without bounds
- The callalloca() function as a way to have large local arrays
In principle I could submit these to upstream for inclusion, but for various reasons I haven't - although I have come close to doing this for callalloca(), as it's relatively unintrusive and I find it useful. (On the other hand, I mainly find it useful for being able to allocate a 256-byte local array to deal with things which could be that large on the Acorn OS, like pathnames, so it may be that on the Apple this is less valuable.) An Acorn port without these would be completely possible and would be simpler (if perhaps more frustrating to develop on) and closer to upstream. However, I think if they're going to be there, they have to be in the core VM rather than in modules.
It would be possible to unpick some or all of these changes in the shell, but the changes for the growable symbol table are pretty intrusive and you might find it easier to start from scratch with the upstream 'cmd.pla' or 'a1cmd.pla' and perhaps just use my port's code as a source of ideas and fragments of code.
The first version of my port posted in this thread (and in the github repo with the 'stardot1' tag) was IIRC based on the upstream Apple I code. The Apple I code is much simpler than the Apple II code - there's no banked RAM support, for example - and of course my port had had less time to diverge from upstream as well. So you might like to take a look at that, and if you want something with the latest upstream features, you could perhaps try porting the latest Apple I VM - maybe using my 'stardot1' tag as a base, or perhaps porting 'a1cmd.pla' but re-using the assembly language part of the latest version of my port.
If you really want to go minimal, you could also consider throwing away the shell and *replacing* it with your own application code. (This is what the --standalone option in my plasmac.py driver does, but it's quite fiddly as it tries to work with arbitrary PLASMA source code.) That way you don't get any dynamic module loading - everything's effectively statically linked up front - but you also avoid wasting RAM on code you don't want. By throwing away the shell, it also automatically removes most of the divergence between my port and upstream. I've created a simple example of this (based off the old 'stardot1' repo for the simplest, least-modified version of the VM) here:
https://github.com/ZornsLemma/PLASMA/tr ... n-stardot1 If you build that, the Acorn "PLASMA" executable file on the SSD is actually just a standalone "Hello, world!" program. Have a look at vmsrc/bbcmd.pla.
To sum up:
- If you want a minimal port which doesn't diverge too much from upstream, I think you might well find it a useful time saver to start with the assembly language part of my port (vmsrc/plvmbb*.s), either as-is or manually removing the features you don't want. Doing this would also mean you'd get to re-use any future work I do to port new upstream versions.
- I am open to be convinced, but I don't think I can factor out any of my changes to the core VM into loadable modules - I've already done this where I thought I could. They could certainly be removed completely in a fork/alternate port, but I think that if they are present, they have to be in the core VM.
- If you do want a minimal port, the upstream Apple I code is probably a good place to start as its hardware is probably most like that of a standard 32K BBC B. The 'stardot1' tag in my repo is an outdated version of such a port which might be helpful to you.
- If you can live without the "environment" provided by the PLASMA shell, you could go very minimal by replacing the shell with your own application.
I'd certainly be happy to contribute to the wiki porting guide but at this rather waffly stage I thought it would be better just to post this here. If you'd like to copy any of this onto the wiki, do feel free!
Cheers.
Steve