EEA index
FileStore
Intro |
NVRAMThe FileStore contains a "CMOS RAM", which is a 146818-type fully programmable battery-backed memory device.This device, hereafter referred to as NVRAM (non-volatile RAM), is used for three purposes:
The NVRAM requires a continuous supply to keep the data intact. This low-current supply is provided by a NiCad battery that outputs 3.6V. The battery is charged by a constant current source from the +5V rail while the power is on. The small cylindrical crystal near the battery (in the E01S, probably similar for E01) provides the time base for the NVRAM. As is common for watches and the like, it operates at 32.768kHz. The variable capacitor near the crystal allows for fine-tuning and, when the server is undergoing testing, the test point (TP1, by the NVRAM chip), can be used to ensure that the ticker is running at exactly 1.024kHz.
The NVRAM's address register is mapped in to memory at
NVRAM allocationsCompiled from a component datasheet and the E01S test software.
Default valuesIf the NVRAM is detected to be invalid, then defaults will be set.
If the battery's charge is marginal, it is possible for bogus data to be stored in the NVRAM and the server will use sensible defaults but not clear the contents of the NVRAM. A suggested workaround is to use !FSUtil to "test" the NVRAM. The first operation it will do is read a copy of the current contents into memory. It will then write zeroes into NVRAM and attempt to read them back. As soon as !FSUtil starts to read back the data, you should switch your FileStore off. Don't worry - !FSUtil will crash whinging about not being able to read back the information.
The remaining bytes, 50 to 63, are not cleared by the FileStore as they are not used.
The FSUser check byteThe FSUser check byte is calculated by taking all ten bytes of the possible FSUser name (whether or not they are actually used in the name) and adding them.If the value exceeds the range that would fit into a single byte, it is clipped to be within range (0 - 255) and one is added to the following byte. In code terms, this would look like: calcbyte% = 0 carry% = 0 FOR offset% = 36 TO 46 calcbyte% = calcbyte% + cmosarray%?(offset%) + carry% IF calcbyte% >= &100 THEN calcbyte% = calcbyte% - &100 carry% = 1 ELSE carry% = 0 ENDIF NEXTIf you would like to test the algorithm yourself, then we know that for the following sequence: S Y S T <LF> <NUL> <NUL> <NUL> <NUL> <NUL> Which in hex is: 53 59 53 54 0D 00 00 00 00 00 00 The check byte value is &61. This is hardcoded into the FS ROM. Here is a JavaScript-enabled way to calculate check bytes. Feel free to view the document source and look at the code.
There is a caveat to be aware of. I do not currently know if the FSUser command clears existing data or if it simply writes new data.
Would the FSUser name area look like this:
NVRAM read codeThe code to perform the reading is:LDA #5 LDX #(<address> MOD &100) LDY #(<address> DIV &100) JSR &FFF1 ; OSWORD RTSWhere address is where you want the result to be stored to (which should not be the same place you decide to poke your code into the server memory). As a BASIC function to prebuild this code segment, it would appear as: buffy%?0 = &A9 buffy%?1 = 5 buffy%?2 = &A2 buffy%?3 = address% MOD 256 buffy%?4 = &A0 buffy%?5 = address% DIV 256 buffy%?6 = &20 buffy%?7 = &FFF1 MOD 256 buffy%?8 = &FFF1 DIV 256 buffy%?9 = &60This code is poked into the FileStore at the address you have decided (with *FSProt Off !). You should then Remote_JSR to your code. Finally, peek the address that you have specified to store the result to. The result is at offset +4; so read back 6 bytes, the result is now in buffy%?4.
The code used by !FSUtil to read the NVRAM is: SYS "Hourglass_On" FOR loop% = 0 TO 63 cmosbuffer%?loop% = FNcmosfetch(loop%) NEXT SYS "Hourglass_Off"This reads all 64 bytes of NVRAM, calling the cmosfetch function, which is: DEFFNcmosfetch(addr%) LOCAL rec% FOR rec%=0 TO 5 : buffer%?rec%=0 : NEXT ?buffer%=addr% PROCcmosassemble(5) SYS "Econet_DoImmediate", 2, &E800, fsstn%, fsnet%, cmoscode%, 10, 10, 2 TO erp% IF (erp% <> 0) THEN call error handler... SYS "Econet_DoImmediate", 2, &E900, fsstn%, fsnet%, buffer%, 6, 10, 2 TO erp% IF (erp% <> 0) THEN call error handler... SYS "Econet_DoImmediate", 3, &E800, fsstn%, fsnet%, 0, 0, 10, 2 TO erp% IF (erp% <> 0) THEN call error handler... SYS "Econet_DoImmediate", 1, &E900, fsstn%, fsnet%, buffer%, 6, 10, 2 TO erp% IF (erp% <> 0) THEN call error handler... =buffer%?4What happens here is the ten bytes of code is uploaded to &E800, and then six bytes are uploaded to &E900. This may seem unnecessary, but it is required in order to ensure that our data area is blanked. Once this has been performed, we execute the remote procedure call to JSR to address &E800. This will cause the code to be executed. Finally, we read six bytes back from the data area. The two 256 byte blocks of memory are &E800 and &E900, both of which are MOS code, but are part of the copy loop and, apparently, are not used after the boot sequence so it is theoretically safe to use these pages for user code. The final thing is the cmosassemble function, which is: DEFPROCcmosassemble(readwrite%) cmoscode%?0 = &A9 cmoscode%?1 = readwrite% cmoscode%?2 = &A2 cmoscode%?3 = &E900 MOD &100 cmoscode%?4 = &A0 cmoscode%?5 = &E900 DIV &100 cmoscode%?6 = &20 cmoscode%?7 = &FFF1 MOD &100 cmoscode%?8 = &FFF1 DIV &100 cmoscode%?9 = &60 ENDPROC The value of readwrite should be 5 (as shown in these examples) to read the NVRAM, and 6 if you wish to write it. All of this code is seriously unoptimised. It was designed to read or write bytes one by one from the NVRAM, and essentially a complete read or write operation means going through the motions 64 times! An easy optimisation would be:
The 146818The Real Time Clock / Non-Volatile RAM (RTC/NVRAM) chip used to hold the date and configuration in the FileStore is an interesting mixture of features and compactness. It uses a multiplexed bus interface where the address and data pins are one and the same, compatible with the 6800 mux circuit and also the 8085 bus. The first access sets the address and the second reads or writes data. This is handled by two pins, the Address Strobe (pin 14) and the Data Strobe (pin 17). Within the FileStore, the device's address and data are mapped into two different locations in memory (&FC00 and &FC04 respectively). The address decode logic will use this to determine whether to instruct the device to set an address or to access internal data.
This is better shown on the schematic below. This is from the E01 as it is less cluttered than the E01S' circuit diagram. The address decode logic has been omitted as it would more than double the size of the picture. |