E01S emulator(yes, really!)

EEA index

Error codes
Disc format
Disc image
Password file
E01 vs E01S

Mem. map
SD card

Misc h/w
Misc info

An emulator?

The latest version is 0.00 (2010/08/08)
This is available as both executables and as source code.


FileStore (executable)

FileStore E01S emulator, "flap closed".
This is not useable. It will start the fileserver firmware, up to the point of probing the floppy drive, however since the majority of the main chips have not yet been implemented...
This is being released to give you an idea of what/how/why.


fsem_setup.exe - 2010/08/08, 1,211KiB
This software is licenced under the EUPL v1.1.

It's a self-installing executable. Contained within is the working executable which is a slow P-code application requiring the VB5 runtime (my "Various Dependencies").
Also present is a native code (plus-plus) version requiring the VB6 runtime.
Both versions require the RTF control.
If you don't have VB6/RTF, you can get it all by installing IconCool editor - www.iconcool.com [this is not a product recommendation].
Having said that, just try it. You may well have what you need. Either it'll crash whinging about DLLs and OCXs, or it'll work...


FileStore (source code)

FileStore E01S emulator, "flap open".
The project sources are being released to encourage you to participate in any way that you can. These are the exact sources used to create the above executable, and may be opened with VisualBasic 5 or VisualBasic 6.

This software is licenced under the EUPL v1.1.

fsem_src_20100808.zip - 2010/08/08, latest, 931KiB
This is the latest source; and is the source used to build the above executables. Refer to the versions file to see what is new.


Outstanding issues

This only includes information on issues in code supposed to be known as working. Stuff not yet implemented or partially implemented is not covered.
  • Verify ADC and SBC for correct carry operation. Is there a 65(C)02 test suite?
    Begun work on implementing my own, using the MonkeyNes scripting as a guide (but it is completely original code/implementation)
  • ... An ASCII search in memdump would be nice. Use !Edit like "[xx][xx]" for non-ASCII, like "[EA][EA]" for NOP,NOP.
  • Check behaviour of "rompatch.txt" if patch data is too short - I think it'll crash or otherwise screw up.
  • ... Not exactly a 'bug', but we really oughta have CPUState work both ways.
  • Documentation menu item should do better - perhaps open ReadMe.txt and Versions.txt in lieu of actual docs?
  • We have a URL launcher, "Help>Support website" ought to come here.
  • ... Should Reset zero the cycle count?
  • ... We have an ADLC (sort of), so we should have an ADLCState.


FileStore EPROM images

The EPROM images provided below are 1988/1989 Acorn Computers; and are provided both to facilitate seeing this emulator actually do something, and also as a resource for people who have a FileStore.
These EPROM images are hosted without permission as Acorn Computers no longer exists - don't Google, there is one now but it is nothing to do with the original - we can all cry absolute bucketloads at seeing Acorn recommends Windows Vista Home Premium & Vista Ultimate AAAAAAAAARRRRGGGGHHHHH!!!!!!!!!!!!!! AAAAAAARRRGGGHHHH!!!!!!!!!!!!!! AAAAAAAAAAAAAAAAAAARRRRGGGHHHH!!!!!!!!!!!!!! AAAAAAAAARRRRGGGGHHHHH!!!!!!!!!!!!!! <pant> <pant> <pant>...
The company went through all sorts of revisions and buy-outs - Element14, Pace, Castle... who owns the rights to the old 6502 code? Do they even know? Does anybody have the sources any more or have they been lost forever?
These EPROM images (as with the others (DNFS etc) on my site) are for hardware that is commercially obsolete. I think Acorn stopped selling the FileStore in the early '90s (confirm?) and the 6502 range is now used either by enthusiasts or a number of installations where it has been doing its job since the '80s. Certainly, if anybody claims loss of profits, it'll have to be a pretty ingenious excuse!
With that in mind, if the relevant current copyright holder objects to my hosting these EPROM images, they need only say. Documented proof will be required, not specifically for me but for the BBC/Econet community as a whole to definitely establish who has the rights in these old bits and pieces. Alternatively, and much to the preference of everybody who is using the older systems on an ongoing basis, it would be greatly appreciated if the copyright holder could release these items into the public domain (aforementioned proof will be required to definitely establish that this all on the level).
Thoughts? Comments? heyrick1973 -at- yahoo -dot- co -dot- uk

  • e01_v131.dat (64KiB)
    E01 (non-stacking) firmware, version 1.31. © 1988 Acorn.
    I think this is for the 'later' version of the E01 as it is very similar to my E01S (including maintenance commands prefixed with "FS").
  • e01s_v133.dat (64KiB)
    E01S firmware, version 1.33. © 1988 Acorn.
    I believe this is the most common version installed in the E01S model. A known difference to the above is the embedded message "Acorn Econet 3.66". I do not know what else is different, perhaps asides from support for multiple harddiscs?
  • e01s_v140.dat (64KiB)
    E01S firmware, version 1.40.00. © 1989 Acorn.
    This is the latest known FileStore firmware. It contains "Acorn Econet 3.70", some better-worded messages, a better (working?) implementation of user space accounting, plus a list of names: "The Stacking FileStore was devised and created by the following; Ram Bannergee, David Burling, Brian Cockburn, Carl Dellar, Joe Dunn, Laurence Hardwick, Andrew Hinchley, Steve Love, Glen Nicholls, Mike Oakley, Brian Robertson, Hugo Tyson, and Jes Wills.".
    The startup (on a real FileStore) is much faster than the v1.33 (shorter delay?) and when used on the emulator it will not reach a state of waiting with the Mode LED blinking. This is because it seems to cycle through the hardware test routine endlessly if something is wrong at startup (refer to accesses in "hwlog.txt" after running the emulator awhile).
If you have a version that is not listed, I would greatly appreciate an image file of the contents of the EPROM(s). The emulator loads 64KiB images, but can join parts if they are 16KiB or 32KiB which means most BBC-era EPROM programmers/readers ought to give results.
Contact me: heyrick1973 -at- yahoo -dot- co -dot- uk


Source code reference

Reference material to accompany the source code.

  • Version log
    Lists changes to the emulator (reverse chronological order); also discusses various points which may be of interest to programmers and are therefore not really suitable for inclusion in the main help and/or "readme".
  • List of modules
    Lists all of the forms and modules present, what they are for, and their status.
  • Example "hwlog.txt" file
    The emulator will report all hardware accesses to currently unimplemented hardware. You can see what it looks like to start up the v1.33 firmware and leave it running a short while...
  • Coding notes
    Miscellaneous coding notes.



  • Why is it slow?
    Read the following section.
  • Why does the main window show one 'PC', while everything else shows something else?
    The main window shows PC now, which is the instruction about to be executed. The other places where PC are shown relate to the current instruction.
  • Why does stepping the disassembler backwards result in gibberish?
    This is because, without foreknowing or making some sort of complicated map of instructions, it is not really possible to 'step back' to the previous instruction. This is because instructions can be between one and three bytes in length, so it will be necessary to know how far back we can go.
    The workaround is just to keep stepping back until the instructions shown 'settle'. For example, consider:
    &E900 : BD 00 2B : ½.+ : LDA &2B00,X
    &E903 : 9D 00 2B : ..+ : STA &2B00,X
    &E900 : BD 00 2C : ½., : LDA &2C00,X
    &E903 : 9D 00 2C : .., : STA &2C00,X
    If the top address of our disassembly is &E903, stepping back once would show:
    &E902 : 2B       : +   : ?? ##INVALID##
    &E903 : 9D 00 2B : ..+ : STA &2B00,X
    &E900 : BD 00 2C : ½., : LDA &2C00,X
    &E903 : 9D 00 2C : .., : STA &2C00,X
    Back another time, to show:
    &E901 : 00       : .   : BRK
    &E902 : 2B       : +   : ?? ##INVALID##
    &E903 : 9D 00 2B : ..+ : STA &2B00,X
    &E900 : BD 00 2C : ½., : LDA &2C00,X
    &E903 : 9D 00 2C : .., : STA &2C00,X
    And back one more time to show, correctly:
    &E900 : BD 00 2B : ½.+ : LDA &2B00,X
    &E903 : 9D 00 2B : ..+ : STA &2B00,X
    &E900 : BD 00 2C : ½., : LDA &2C00,X
    &E903 : 9D 00 2C : .., : STA &2C00,X
    This is what I mean about letting the instructions "stabilise".
  • Why, when starting the emulator, does the memory dump not work?
    If you enter the disassembler at this point, you will see up the top of the window that it says "READING FROM EPROM".
    The memory dump, for speed, will only read from RAM and as such will be of very limited use until the EPROM contents have been copied to RAM and the latch set to mask out the EPROM and send all memory accesses (aside from hardware) to RAM. This will occur after around three hundred and fifty thousand cycles, which is about 0.18 seconds (!) of emulation time.
    Given this, it was decided that permitting the memory dump access to both EPROM and RAM was not worth the potential delay of the code to handle this.
  • Fiddling flags in the CPU status window doesn't seem to have any effect?
    That's right, it is read-only.
  • Can we do without that start up 'setup' dialogue?
    Yes, as of the 2009/08/02 build there are some command line options, namely:
    -start    Start the emulator, no "setup"
    -run      Start emulation normally
    -halt     Start with the processor halted
    -open     Start with front flap open
    -closed   Start with front flap closed
    This takes into account, and updates, previous settings. If you didn't specify to start with the processor halted, using "-start" will suffice, else you should use "-start -run", or if you would rather start halted, you can use "-start -halt".
    Passing either "-?" or "-help" will remind you of this, then exit.


Why is it so slow?

On an Asus eeePC 901 with an Intel Atom processor clocking at 1.6GHz, the timings from clicking the start button to the first time the MODE indicator goes off is:
  • Fast version - 13.1s
  • Demon version - 12.6s
  • P-code version - don't ask...
In emulated time, this is about five and a half seconds, so the emulator is running a 2MHz CPU at a rate approximately 850kHz; or a little under half speed.

This is due to a number of factors... Firstly it is written in VisualBasic, which will suffer a speed loss compared to C, even when in native .EXE form. VisualBasic isn't really a suitable language for writing an emulator, which is why I am one of the few who have attempted such a thing.

Secondly, the code is written with an aim to being clear. I don't doubt that a rewrite of various parts could do a lot to boost the speed, but how obfuscated would it appear then? Many years ago I wanted to write an add-on for a bulletin board server that provided InfoCom-style adventure games. I spent weeks pulling apart an interpreter in order to try to recompile it under RISC OS, and eventually gave up as the code was SO hairy it was unreal. Tricks like that can eke out loads of speed, but I'd rather a slow program that everybody can understand!

Finally, my FileStore emulator offers rather more facilities than you would find on other typical emulators. Go on, try to find this on B-Em:

Following every breath the CPU takes...
Don't waste your time. B-Em doesn't offer this. It's because the aims are different. I am not trying to make the best, fastest, and slickest emulator. If you want a rocking Beeb era emulator - BeebEm is for you.
Let's face it, unless you make a habit of collecting obscure emulators, you are probably here because you want to play with your FileStore, only you'd rather prototype your code on a virtual one (for all the reasons given in the rationale). You see, the majority of people using B-Em or BeebEm are likely to use the machine for retro games, or applications without the inconvenience of having a 'real' Beeb on their desktop too. In most cases the code is already written. In fact the code might easily be nigh on a quarter century old!
This is not so for FileStore users. It is an embedded device which demands little in the way of management. Its firmware is in an EPROM. Power up, it is ready in around ten seconds. The end. So why emulate it? The primary reason for emulating this device is to permit modifications to the hardware to be attempted. It's all very well to say "we'll rip out the SCSI harddisc code and replace it with some way to talk to an SD hanging off the printer port; oh and we'll rip out the printer code and replace it with a built-in formatter." That's what I'd like to do, but I can't say "make it so" and have it happen.
Bare hardware is unforgiving. Discs are easy to trash. You could tell the floppy to spin forever and it will do it, or leave the processor awaiting an interrupt from something that will never interrupt. And to look at the server... nothing. It won't go green. It won't throw up on the floor. It won't wet itself. In fact there will not even be internal strife and turmoil as it's only doing what you told it. This is where the memory analysis and CPU core tracing (etc) stuff comes in handy - it lets you do the impossible. It lets you look inside the hardware. It, in many cases, will let you directly modify the hardware. And as you have the source code, you can set up all sorts of traps and such if the breakpoint system isn't enough for you. It's all tailored towards making your hacking as pleasant as possible before you get to all the fiddling with programming EPROMs and such. And because of this, the emulator takes another speed hit.

Here's something else you won't find on a lot of emulators:

Memory display, oh and it's editable too!


Important ICs

CPU 65C102 [2MHz]
RAM 64KiB, 2×4464 in 64K×4bit side-by-side layout
EPROM 64KiB, 27512
Network Master/A-series Econet module (6854 ADLC)
Floppies 2×DSDD (~640Kb) driven by 2793 FDC
Harddisc Logic-gate SCSI-I implementation (?)
RTC/NVRAM 146818 RTC (64 bytes inc. RTC/regs)
Printer BBC-like parallel port from 65C22 VIA


Memory map

In the hardware page (&FCxx), addresses MOD &40 are equal. The addresses in square brackets are alternative possibilities due to how the address decoding works; though the first address given is the 'legal' address.

&0000 - &00FF Page Zero
&0100 - &01FF Hardware stack
&0200 - &03FF MOS workspace (512 bytes)
&0400 - &7BFF FS code (30KiB)
&7C00 - &E7FF FS workspace (28KiB)
&E800 - &FBFF MOS code (5KiB)
&FC00 - &FCFF Memory-mapped hardware (256 bytes)
&FC00[- &FC03] RTC address register
&FC04[- &FC07] RTC data register
&FC08[- &FC0B] [READ] EPROM/RAM access latch (always selects RAM)
&FC08[- &FC0B] [WRITE] Miscellaneous functions latch
   bit 0  Floppy 1 (left) select
   bit 1  Floppy 2 (right) select
   bit 2  Floppy side (0|1) select
   bit 3  Access to NVRAM possible if set
   bit 4  FDC Disc Density (active low)
   bit 5  FDC MasterReset (active low)
   bit 6  FDC Test (active low)
   bit 7  Mode (red) LED
&FC0C - &FC0F 2793 FDC (4 bytes, 4 registers)
&FC10 - &FC1F 6522 VIA (Printer; 16 bytes, 16 registers)
&FC20 - &FC23 6854 ADLC (Econet interface; 4 bytes, 4 registers)
&FC24[- &FC27] Network interrupt disable (any access here)
&FC28[- &FC2B] Network interrupt enable (any access here)
&FC2C[- &FC2F] Front flap switch status, present on bit 6
E01 has a SW3 on bit 7, not present on E01S
        &FC30 HD data (is WRITE buffered)
        &FC31 [READ] HD status (is WRITE buffered)
   bit 0  Message
   bit 1  Busy
   bit 2  - (low)
   bit 3  - (low)
   bit 4  !IRQ
   bit 5  Request
   bit 6  Input/Output
   bit 7  Command/Data
        &FC32 [WRITE] HD select
        &FC33 [WRITE] HD enable IRQ
       0 -  Disable
       1 -  Enable
&FC40 - &FC7F Repeat of &FC00-&FC3F.
&FC80 - &FCBF Repeat of &FC00-&FC3F.
&FCC0 - &FCFF Repeat of &FC00-&FC3F.
&FD00 - &FFE2 MOS code (738 bytes)
        &FFE3 OSASCI vector (firmware - JMP xxxx)
        &FFE7 OSNEWL vector (firmware - JMP xxxx)
        &FFEE OSWRCH vector (firmware - JMP xxxx)
        &FFF1 OSWORD vector (firmware - JMP xxxx)
        &FFE4 OSBYTE vector (firmware - JMP xxxx)
        &FFFA NMI vector (hardware - an address)
        &FFFC RST vector (hardware - an address)
        &FFFE IRQ vector (hardware - an address)


Interrupt sources

There are two types of interrupt in the FileStore - the NMI (non-maskable interrupt) and the normal IRQ. An NMI can interrupt an IRQ already in progress.

There are no "events" in the FileStore. It is an interrupt-driven system. As far as I am aware, there are no random "housekeeping" functions; any internal operations are likely to be based upon the RTC ticker. The RTC ticker actually ticks once every second. It is an interrupt to say the RTC has been updated. This is the lowest granularity in the system, the centisecond ticker (part of the vaguely BBC-like "MOS") is updated by 100 each time!
Disc activity will be initiated by the system, either in startup or in response to a user request. The response will be interrupts which will usually result in some sort of response to the user; though it seems at cursory examination as if many of the disc communications are polled.
While this may seem rather inefficient, it is usually a lot quicker to simply sit and wait for data you know will be coming quickly instead of going through the whole interrupt (or NMI?) sequence over and over. The floppy generates a number of interrupts. But try to find interrupt handling code for the harddisc interface...
A great example of a compromise here is the Econet ADLC NMI handler (we can't rely on constant or fast responses from the ADLC so it works off NMIs) - there are actually several different NMI handler routines and which one is used depends on what we're doing - are we keeping an ear open for scout packets? Are we going to transfer a chunk of data? They each have different requirements and as such different NMI code is used to make the system as fast as possible... [note - this works because Econet is a 'state machine', and only one transaction at a time can take place on the network]
User commands are passed into the server via the network and, as such, generate interrupts from the network card. Finally, the printer causes an interrupt to say each character has been received and dealt with.

NMIs can be generated by:

  • The floppy disc. The FDC2793 has, like, no buffering so when a byte is ready it absolutely must be read. A 1MHz CPU would struggle to keep up with the data, so you can understand there is little room for la-de-dahing...
    [this may not be entirely accurate - are FDC NMIs per byte, or for status? I'll need to check...]
  • The Econet. The ADLC will interrupt when something needs to be checked. Note, however, that the server will disable the Econet NMI during floppy disc activity...

IRQs can be generated by:

  • The parallel port, so we know a byte has been ACKed.
  • The HDC. Harddiscs have a buffer so can run as IRQ services, not NMI.
    [this is as mentioned in the service guide; however I can't find a mention of the HD adaptor code anywhere in the IRQ or NMI service routines, it appears it actually polls for a response]
  • The RTC. The NVRAM/RTC is programmed to generate an IRQ every time the RTC is updated, which occurs once each second. That is the system ticker! Accordingly the centisecond timer operates in units of a hundred. As you might expect, there appear to be many software delay loops for when shorter intervals are required.

I do not recall system behaviour on the printer buffer being "full". The service manual implies that the system will freeze, but we are looking from the aspect of calling OSWRCH instead of actually spooling a print job from a user terminal...


The IRQ handler

The IRQ handler, when entered, first checks to see if the IRQ is from the VIA's Timer1. This is used in a one-shot mode, something to do with the ADLC (perhaps as a timeout for communication? I am not entirely sure yet).
If it is Timer1, we jump via a pre-defined jump table that is set up.

If the IRQ was not Timer1, we look to see if it was an interrupt from the RTC. If it was the RTC interrupting, we read the RTC (if safe to do so, this is when the NMI handler for the ADLC will be awaiting scout packets and there is no on-going network communication) and build the FileServer format 5-byte time value. Yes - we have don't perform any RTC capabilities in the MOS, we just read out the RTC every second, which necessitates turning the network IRQ off, and back on again, six times! Finally the centisecond ticker is updated by having 100 added.

Still here? Then we check the printer interrupt. If it is this, we look at the buffer. If there is more data to be sent, we read the byte and write it to IORA (port A). This is all that is required as the system sets up the VIA to operate port A with 'pulse' handshaking (CA2), so when a byte is available on the data lines, CA2 is pulsed for one cycle of the 2MHz clock (which seems to be a lot shorter than the standard 4.7µs expected on parallel port hardware!). This controls the !STROBE output.
When the printer takes the byte, it will pulse !ACK low which will cause an interrupt, which will start this process over...

The NMI handler

Upon an NMI, the network interrupt is disabled. The server looks to see if the ADLC caused the interrupt. If it did, it is handled... If this is the first ADLC interrupt, we look to see if it is a scout packet. If it is and it is ours, we rewrite our NMI handler vector to point to a handler for ADLC data (as further data will be a continuation, not a scout (actually this all happens in three stages, but the description is generally correct)). If not for us, we flag to discard the frame.
The FDC is then checked (the ADLC code will 'fall through' to check the FDC).

I am still working on untangling the FDC interrupt code. It looks as if the default handler will read the FDC status in order to clear the interrupt, then ignore it. It is possible that this is what happens until such time as a disc operation actually takes place?

Likewise, I am still working on how/where exactly the SCSI host adaptor fits into the equation. Upon a cursory examination (of the v1.31 firmware), it appears as if the SCSI system does not use IRQs. The IRQs appear to be disabled twice when checking for the hardware, and never re-enabled. In addition, it seems as if the server 'polls' the harddisc awaiting a result. Given the overheads of reading data from a harddisc under interrupt, and the fact that the harddisc, once data located, ought to be more or less able to keep up with the server, it would make more sense to simply poll for the reply.

Copyright © 2010 Rick Murray