View unanswered posts | View active topics It is currently Fri Apr 19, 2024 9:15 am



Reply to topic  [ 24 posts ]  Go to page Previous  1, 2
 porting BCPL 
Author Message

Joined: Sun Oct 14, 2018 5:05 pm
Posts: 62
oldben wrote:
I still plan to port BCPL at some point, but still am tweeking the instruction set of my computer and assembler.
Right now I am debugging a version the meta-ii compiler with a symbol table. This means my cross assembler needs
about 24Kb for the symbol table data because of the longer names used. I expect another 24k for the code space since I
have 16 bit offsets for labels.
I have 48kb user space and 32kb kernel space reserved at the moment. BCPL may shoe horn into a tiny space
but other software may need more room.
Ben.


You won't be able to run the current compiler in that, (48KB of binary and needs 2-300KB of in-core temporary storage) but for reference, my CINTCODE VM thingy is 16KB of 65816 assembly code. It could be a lot less (about 10KB from memory) if I didn't in-line a lot of the code - but it also would run slower, so there is a trade-off there.

Some examples of code in my system:

My BCPL editor is 1772 lines of code and compiles to 6KB of CINTCODE. I have a C version which compiles to 16KB of 6502 assembler code.

Of-course my BCPL system requires a run-time library and that's a few dozen KB, but it can be pared back.

Then there is the 10KB of Machine Operating system - written in 65816 assembler.

Harking back to the old days when I ran the 16-bit BCPL on a BBC Micro - that had the interpreter and some utilities in a 16KB ROM with the MOS in the existing 14KB ROM, Disk filing system in another 16KB ROM, but you had 28KB of RAM or so which could run the compiler, etc. as required. Sadly the sources of that version of the compiler have been lost (according to Martin Richards).

Cheers,

-Gordon


Mon Feb 27, 2023 9:16 pm
Profile

Joined: Mon Oct 07, 2019 2:41 am
Posts: 592
drogon wrote:
You won't be able to run the current compiler in that, (48KB of binary and needs 2-300KB of in-core temporary storage) but for reference, my CINTCODE VM thingy is 16KB of 65816 assembly code. It could be a lot less (about 10KB from memory) if I didn't in-line a lot of the code - but it also would run slower, so there is a trade-off there.

Some examples of code in my system:

My BCPL editor is 1772 lines of code and compiles to 6KB of CINTCODE. I have a C version which compiles to 16KB of 6502 assembler code.

Of-course my BCPL system requires a run-time library and that's a few dozen KB, but it can be pared back.

Then there is the 10KB of Machine Operating system - written in 65816 assembler.

Harking back to the old days when I ran the 16-bit BCPL on a BBC Micro - that had the interpreter and some utilities in a 16KB ROM with the MOS in the existing 14KB ROM, Disk filing system in another 16KB ROM, but you had 28KB of RAM or so which could run the compiler, etc. as required. Sadly the sources of that version of the compiler have been lost (according to Martin Richards).

Cheers,

-Gordon


What is with this 2-300K in core temp storage?
I need a 32 bit version (IBM360?), how big is that?
Ben.


Mon Feb 27, 2023 10:51 pm
Profile

Joined: Sun Oct 14, 2018 5:05 pm
Posts: 62
oldben wrote:
drogon wrote:
You won't be able to run the current compiler in that, (48KB of binary and needs 2-300KB of in-core temporary storage) but for reference, my CINTCODE VM thingy is 16KB of 65816 assembly code. It could be a lot less (about 10KB from memory) if I didn't in-line a lot of the code - but it also would run slower, so there is a trade-off there.

Some examples of code in my system:

My BCPL editor is 1772 lines of code and compiles to 6KB of CINTCODE. I have a C version which compiles to 16KB of 6502 assembler code.

Of-course my BCPL system requires a run-time library and that's a few dozen KB, but it can be pared back.

Then there is the 10KB of Machine Operating system - written in 65816 assembler.

Harking back to the old days when I ran the 16-bit BCPL on a BBC Micro - that had the interpreter and some utilities in a 16KB ROM with the MOS in the existing 14KB ROM, Disk filing system in another 16KB ROM, but you had 28KB of RAM or so which could run the compiler, etc. as required. Sadly the sources of that version of the compiler have been lost (according to Martin Richards).

Cheers,

-Gordon


What is with this 2-300K in core temp storage?
I need a 32 bit version (IBM360?), how big is that?
Ben.


The BCPL compiler hasn't stopped being developed and every now and then Martin does some work on it - the large space is because over the years memory got cheaper, so it was easier to read in all the source and parse and build the syntax tree in memory at the same time... And have the compiler as one program rather than 2 separate unit working on intermediate files. The default on the current compiler is somewhat generous but that's about what I managed to reduce it too to get it to compile the compiler. (Which takes a whole 2 seconds on my desktop). The ompiler features 3 different code generators and it's possible to remove the one(s) you never use - I've not bothered even though I only every generate CINTCODE. (The others being the older OCODE and SIAL - an intermediate designed to be easier to translate to native code).

The compiler binary is the same size no matter what system its running on, so about 48KB - because it's bytecode.I did look at splitting it - it's in 2 separate files with well defined functionality but didn't need to in the end. CINTCODE opcodes are of the form: Load small constant (one byte), load bytes (2 bytes), load halfword (3 bytes) and load word (4 bytes). If you never used 32-bit constants then you might get it to output code to work in a 16-bit system but I've never looked into that.

My CINTCODE VM/interpreter is smaller when hand coded on a 32-bit RISC-V system - about 10KB. It runs like a dream on that system compared to the 65816 and is much more efficient cycle for cycle.

I'll give a complete memory usage on my existing system in the next day or 2 (I'm away from home right now), so you can judge sizes, etc. The run-time library is significant, but it can be hacked and trimmed down - it's loaded at boot time as it's shared between the OS/CLI and anything you run including running imps (background processes).

-Gordon


Tue Feb 28, 2023 2:20 pm
Profile

Joined: Mon Oct 07, 2019 2:41 am
Posts: 592
I don't see problems with updating stuff, as long as the older versions can still run.
Newest is not always better.
Right now I adding as simple stack heap to my system bios.
mheap(size,width) is the call, if size is zero it returns free space on the heap.
This will let me get a simple languge bootstapped up as one pass compiler.


Tue Feb 28, 2023 9:05 pm
Profile

Joined: Sun Oct 14, 2018 5:05 pm
Posts: 62
This is the run-time memory usage of my Ruby BCPL-OS system:

This represents the run-time libraries that are shared between all executables and background processes (imps).

Code:
  #x004400, InUse,   0, Sz:     37 <rubyOs     >
  #x004425, InUse,   0, Sz:    327 <getvecLib  >
  #x00456C, InUse,   0, Sz:    322 <stringLib  >
  #x0046AE, InUse,   0, Sz:     73 <miscLib    >
  #x0046F7, InUse,   0, Sz:    343 <devLib     >
  #x00484E, InUse,   0, Sz:    100 <sortLib    >
  #x0048B2, InUse,   0, Sz:    103 <gpioLib    >
  #x004919, InUse,   0, Sz:    174 <imp        >
  #x0049C7, InUse,   0, Sz:    347 <streamIO   >
  #x004B22, InUse,   0, Sz:    297 <vdu        >
  #x004C4B, InUse,   0, Sz:    366 <witeFmt    >
  #x004DB9, InUse,   0, Sz:    292 <reads      >
  #x004EDD, InUse,   0, Sz:    424 <rdargs     >
  #x005085, InUse,   0, Sz:    239 <enargv     >
  #x005174, InUse,   0, Sz:   1421 <cli        >
  #x005701, InUse,   1, Sz:     24
  #x005719, InUse,   1, Sz:     24
  #x005731, InUse,   1, Sz:     10
  #x00573B, InUse,   1, Sz:     34
  #x00575D, InUse,   1, Sz:    260
  #x005861, InUse,   1, Sz:     31
  #x005880, InUse,   1, Sz:     31
  #x00589F, InUse,   1, Sz:     54
  #x0058D5, InUse,   1, Sz:      6
  #x0058DB, InUse,   1, Sz:     54
  #x005911, InUse,   1, Sz:      5
  #x005916, InUse,   1, Sz:      5
  #x00591B, InUse,   1, Sz:      6
  #x005921, InUse,   1, Sz:     54
  #x005957, InUse,   1, Sz:      6
  #x00595D,  Free,   0, Sz: 108191
  #x01FFFC, InUse,   0, Sz:      0
5469 / 108191 : 4%
===
  #x000380, InUse,   0, Sz:     18
  #x000392, InUse,   1, Sz:     36
  #x0003B6, InUse,   1, Sz:     36
  #x0003DA,  Free,   0, Sz:   7202
  #x001FFC, InUse,   0, Sz:      0
90 / 7202 : 1%


Things to note:

The numbers next to Sz: are in words - of 4 bytes. Several of thee libraries aren't actually needed for a cut-down system - I'll detail them below:

rubyOs: This is the interface library between the BCPL OS and the underlying native '816 rubyOs. It's the low-level stuff and if you're familiar with the Acorn MOS, then osByte, osWord and osClie will be familiar.

getvecLib: Getvec is the BCPL equivalent of C's malloc. Allocates memory from the heap and frees it up, as well as merge. Note: In this system there are 2 heaps - one is "fast" RAM, the other normal RAM. Fast RAM here is used for the global vector and stacks. This is a peculiarity of the 65816 CPU - Fast RAM is the first 64KB bank of RAM and can be accessed using 16-bit addressing rather than extended 24-bit addressing. It's an optimisation that's worthwhile, but it means program stacks are limited in size.

stringLib: - The usual string stuff like strcat, strcmp and so on. Some BCPL peculiarities.

miscLib: Stuff that doesn't fit anywhere in particular - random number code, stop, abort...

devLib: Handles low-level devices.

sortLib: Generic sort routines.

gpioLib: GPIO for the on-board VIA - very system specific.

imp: Handles Imps - background tasks - lets you create and kill them [impusPartum(), impusNetum (), impusMortem()] and a few other misc. things.

streamIO: This is the BCPL streams library - handles file open/read/write/close in the BCPL streams manner.

vdu: Specifics for the output terminal device - provides cursor manipulation on a text terminal and graphics. The VDU subsystem actually is the same the on the BBC Micro, but programs just call high level routines and the system works out of you're on an ANSI terminal, or dedicated "RubyTerm" terminal, etc.

writeFmt: Printf and friends.

reads: Read string - from console or file - provides history and line editing.

rdargs: enargv: command-line handling - the traditional BCPL style or C style argv/argc.

cli: The command-line interpreter.

The lines without any tag are bits of RAM allocated by the CLI and other libraries for IO buffers, command-line history and so on.

The bottom section has 2 allocations at boot time: 2 blocks of 36 words or 128 bytes + allocation overhead (of 4 words). These are stacks.

The BCPL global vector is another thing to note: It's the linkage between programs that want to call routines that exist in different files. There is no linker in BCPL so you sort of have to do it by hand. This means you can load your own code, change the entry in the global vector to point to your code and then you have replaced the system code. Obviously this is open to all manner of interesting things, especially if this were ever a multi-user system but in practice as long as you program with constant vigilance the system is very robust. Additionally, the system actually creates a copy of the global vector for user command unless explicitly instructed not to on a command by command basis. This makes it even more robust, but obviously without any sort of MMU you can still render the system unusable very quickly should you choose.

To save RAM it might be possible to load a program on-top of the CLI program, but then you'd need to load the CLI after. I think this is sometimes done in CP/M systems where you can overwrite COM if you need the extra RAM.

And again, there is a lot of system libraries you might not need to save even more RAM.

There have been other operating systems written in BCPL in the past - "OS6" which ran on the Modular 1, described as:

Quote:
Modular One has a l6-bit word, and a cycle time of 7S0nS.
Our complete configuration includes 32K of core, Fast paper tape
input/output, a 1M word disc, a multiplexer for several consoles,
a line printer and a clock, but the machine was originally deliv­
ered wi thout the last four items. Our initial e £fort was there­
fore restricted to a single user system wi th no permanent file


(Imperfectly OCRd from a PDF of a photocopy - original here: https://www.cs.ox.ac.uk/files/3230/PRG08.pdf )

But that was back in 1971 and I suspect speed-wise is probably on-par, or a shade faster than my '816 implementation although I have the luxury of more RAM, 32-bits and a floating point co-processor)

Anyway, enough for now, and I'll leave you with the conundrum of how to load getvec into RAM when you need getvec to initialise RAM to give you space to load getvec the first place ;-)


Cheers,

-Gordon


Wed Mar 01, 2023 11:52 am
Profile
User avatar

Joined: Sun Dec 19, 2021 1:36 pm
Posts: 72
Location: Michigan USA
Quote:
(Imperfectly OCRd from a PDF of a photocopy - original here: https://www.cs.ox.ac.uk/files/3230/PRG08.pdf )


Thank You for posting this link! Interesting reading.


Wed Mar 01, 2023 11:21 pm
Profile WWW

Joined: Sun Oct 14, 2018 5:05 pm
Posts: 62
mmruzek wrote:
Quote:
(Imperfectly OCRd from a PDF of a photocopy - original here: https://www.cs.ox.ac.uk/files/3230/PRG08.pdf )


Thank You for posting this link! Interesting reading.


Also, the early Amiga DOS was written in BCPL, so there is a little more OS history about it...

Makes me feel I ought to write some documentation about my BCPL OS... It has more or less the same functionality as OS6 above - actually that document was a good reference and gave me encouragement to write it in the first place.

What I'd like to do in my system is implement something similar where it's multi-user, but only one user at a time. (Is there a name for that?) CP/M sort of had "user" areas but I felt it was more a bodge - my thoughts are a separate disk partition (or directory) per user with a common partition for system software and a "login" sort of program.

It gets to be too close to Unix though, but I've thought long and hard about an alternative way to represent it - The P system was sort of menu driven which I was never a fan of, I've never really used VMS, but it's just another command-line thing, right? Primos? Same command-liney idea, so ... Oh well, another thought for another place...

-Gordon


Thu Mar 02, 2023 11:55 am
Profile

Joined: Mon Oct 07, 2019 2:41 am
Posts: 592
The problem with CP/M is that they had no real disc i/o, in the 70's and 80's. With a 8' SSD floppy who needed sub directories.
DOS had a fat system but that was because that developed from Disc Basic, and you had 64Kb of ram. By the time DOS 2.0 developed (sub directories?) the era of 8 bit computers was over.
Did BCLP have sub directories?


Thu Mar 02, 2023 5:52 pm
Profile

Joined: Sun Oct 14, 2018 5:05 pm
Posts: 62
oldben wrote:
The problem with CP/M is that they had no real disc i/o, in the 70's and 80's. With a 8' SSD floppy who needed sub directories.
DOS had a fat system but that was because that developed from Disc Basic, and you had 64Kb of ram. By the time DOS 2.0 developed (sub directories?) the era of 8 bit computers was over.
Did BCLP have sub directories?


BCPL is a programming language not an operating system.

The whole disc filing system thing somewhat irks me - Apple had a DOS that supported long filenames in 1978 and their ProDOS supported directories, (although shorter names) a few years later.

Unix had directories in the mid 70's.

So why didn't Microsoft initially write a filing system that had directories? I'm sure the answer is along the lines of it being based on CP/M and "time to market" and so on, but it's all a bit of a hack on a hack.

My Ruby system has a filing system that supports directories and longer filenames and unlimited files per directory - but it's not part of the BCPL OS, not even part of the 6502/65816 side - it's written in C and runs on the board host processor (ATmega 1280p), so is usable from 6502/65816 programs - and as my BCPL OS runs on the '816 side, it can access the same filing system in a similar manner.

I have a plan to make a native filing system for the BCPL OS written in BCPL - all I need to do is expose a block interface from the host side to the 65xx side. (then write it, or more likely port the C version to BCPL).

But there lies more problems - My filing system is actually very ProDOS like in things like block/file allocation and so on with the same limitations of disk size and file size. However, 32MB is big enough for this for now. The down-side is that the SD card is only usable in the same system - I can't plug it into a PC and read/write files, although it ought to be possible using the FUSE interface under Linux, but I've not even thought about that yet.

However - to keep vaguely to the forum ideals; BCPL - runs on AnyCPU :-)

-Gordon


Thu Mar 02, 2023 6:32 pm
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 24 posts ]  Go to page Previous  1, 2

Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software