A Grail Millennium Project

White Paper

History | Preface | TOC

This document is maintained by the author, Lewis A. Sellers, somewhere in the mountains of East Tennessee, the United States of America. It is an informal technical document for a works in progress project called Grail Millennium, or fully, The Minimal Operating System of Object Class Interfaces Holy Grail for the Millennium. In other words, for a new, easy to use, long-lived operating system.

Copyright Notice

This document and all material therein, unless otherwise stated, is Copyright © 1995,1996, Lewis A. Sellers. All Rights Reserved. Permission to distribute this document, in part or full, via electronic means (emailed, posted or archived) or printed copy are granted providing that no charges are involved, reasonable attempt is made to use the most current version, and all credits and copyright notices are retained.

Distribution Rights

All requests for other distribution rights, including incorporation in commercial products, such as books, magazine articles, CD-ROMs, and or computer programs should be made to the primary author Lewis Sellers.

Warranty and disclaimer

This document is provided as is without any express or implied warranties. This is a work-in-progress, and as such will contain outdated or as yet uncorrected or substanstiated assumptions. The author, maintainer and/or contributors assume no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

WWW Home Sites

You can currently find home sites to this project at If you can not reach them, or they seem to be down, do a key word search on AltaVista, Lycos, or the Web Crawler search engines.

Contact Email

The primary author of Grail Millennium should be reachable at lsellers@usit.net.

Preface | TOC


OCI/Spec | LONG-TERM MEMORY

DESIGNER

Lewis A. Sellers (aka Minimalist) lsellers@usit.net

CRITIQUED BY

DRAFTS

TOC


(a0.50)

The Philosophy

Grail itself is an object-oriented system. Merge this with my desire to completely do away the static boring far-too-generalized GUI that most operating systems present and you have the seeds by which the Grail file system sprang.

The filesystem's core difference with many others is that allows a file to hold any information associated with it with it, thus allowing you to divorce yourself from a GUI and rely upon a metaphoric interpretation of the file system for navigation through itself, etc.

An Brief Overview

The Grail File System is rather unique. Grail utilizes a two-branch file system with dptr (32-bit dwords on Intel processors) layered IDs. That is, for instance, filenames, etc are treated as extraneous information in the associative branch, thus granting them a variable ASCIIZ/UNICODEZ length in the range of 4gb (on intel machines).

Each file is composed of a BINDING, an ASSOCIATIVE BRANCH and a DATA BRANCH. The binding contains a 32-bit ID relative to the current subdirectory (which also has a 32-bit id), groups of file flags, and couple 32, 64, etc bit values containing the pointers to the beginnings of each branch and their lengths.

The DATA BRANCH contains the raw data of the file.

The ASSOCIATIVE BRANCH contains everything else you'd every want to know about the file. It is: ICO, INI, thumbnail, comment file, FILE_ID.DIZ, prefs, read_me.1st, copyright notice, registration key, save game folder, and metaphor guise descriptor, etc all rolled into one. Any application/object in the Grail FS generally uses it's own associative branch to keep track of all things pertaining to itself. NO EXTERNAL FILES ARE NECESSARY.


Table of Contents

Legal NoticesWho gets sued and why
HistoryChanges and who made them
PrefaceAbout the FS and the people that make it

OverviewAn Overview of File Systems
AnatomyThe structure of a file
HeirarchyThe heirarchy of file objects


TOC

A File Systems Overview

BY | Lewis Sellers lsellers@usit.net

The Philosophy

Grail itself is an object-oriented system. Merge this with my desire to completely do away the static boring far-too-generalized GUI that most operating systems present and you have the seeds by which the Grail file system sprang.

The filesystem's core difference with many others is that allows a file to hold any information associated with it with it, thus allowing you to divorce yourself from a GUI and rely upon a metaphoric interpretation of the file system for navigation through itself, etc.

An Overview

The Grail File System is rather unique. Grail utilizes a two-branch file system with dptr (32-bit dwords on Intel processors) layered IDs. That is, for instance, filenames, etc are treated as extraneous information in the associative branch, thus granting them a variable ASCIIZ/UNICODEZ length in the range of 4gb (on intel machines).

Each file is composed of a BINDING, an ASSOCIATIVE BRANCH and a DATA BRANCH. The binding contains a 32-bit ID relative to the current subdirectory (which also has a 32-bit id), groups of file flags, and couple 32, 64, etc bit values containing the pointers to the beginnings of each branch and their lengths.

The DATA BRANCH contains the raw data of the file.

The ASSOCIATIVE BRANCH contains everything else you'd every want to know about the file. It is: ICO, INI, thumbnail, comment file, FILE_ID.DIZ, prefs, read_me.1st, copyright notice, registration key, save game folder, and metaphor guise descriptor, etc all rolled into one. Any application/object in the Grail FS generally uses it's own associative branch to keep track of all things pertaining to itself. NO EXTERNAL FILES ARE NECESSARY.

"Mm. Ok, but what's all that mean?", you might ask.

It means that, a little like the Macintosh systems, you can store information associated with a file in a different branch (fork) of that file. Think of a saddle bag, if that helps. One side of the bag holds the actual data or program of a file, the other side holds information about the file which may include it's name, the authors name, a graphic icon representing the file, some user preferences on how to use the file, it's x/y/z location on the screen, etc etc. Almost every bit of information relating to that file is stored in it's associative branch. Nice, neat and tidy.

One of the first things people notice about this, is that the file's name itself is held in the associative branch just like any other information. And yes, this does mean that on the current Intel platforms filenames can be up to a little over 4 billion characters in length (or 2 billion if using Unicode).

I don't want to hear anyone complaining about filename lengths being too short from now on, ok? :-)

Anyway, the Grail FS can either use it's own partition, or exist on a DOS partition as a huge permanent file (similar to a Windows SWAP file). There are only a few slight differences to the core, and NONE to the application.

Grail tries to hide all the differences between devices. Grail does not try to adapt it's interface for new or badly designed storage devices, it either subsumes them with Grail FS spec drivers, or just does not support them.

The file system is the only part of the core that is required to upgrade itself on a device per device basic. Filesystem devices include standard floppy, hard drive and tape backup units, as well as modems, 16650 devices, and ethernet connections.

A History: The Evolution of the GRAIL Filesystem

It all began when I decided to get rid of the horrid FAT filesystem of DOS. But the information describing how the file mapped onto the storage device had to be held somewhere. Thus, after forming the idea that each file should manage its own such information, the file associative branch was born.

Initially the file associative branch only contained this said filemap information, and was fairly ridged. After a while however, the desire to add in both practically infinite file names and bind related files such as the .INIs, etc into one rapidly accessable place resulted in the revision of the associative design to also hold several binary and string variables.

filemap

mac

metaphor

It was after a somewhat argumentative, though construction, discussion on IRC #coders 2/10/95 with OS2MAN that I went on a search for more information on other file systems, especially the HPFS which OS/2 taunts....

os/2

cts2p

File and Object Names

There is some confusion related to the proper usage of file and object names. In general you can use any character at all in either ASCII (8-bit) or UNICODE (16-bit), however there a few special characters that can not be part of a name, but are considered control characters. They are: NULL, ";", ":", "/" and NEWLINE.

NULL is character code 0. It represents the end of a character stream.

A colon, ":", represents the division between either a title and a subtitle or between an object name and it's instance name. For example this is a title/subtitle name "STAR WARS:A New Hope". And this is a class/instance name "METAPHOR:The Natural Landscape".

A semi-colon ";" usually represents the series number. For instance "X-men:Trading cards;7" might represent the 7th in the series of X-Men trading card pictures. It is also used for extra attributes such as revision or fragmentation numbers, in that order.

The right slash "/" prefixed to a name section indicates a folder, thus it's also called a folder mark. For example "public/readme_please", pointer to the readme_please document in the folder public. Using a folder mark without a name before it indicates that you wish to start with the NULL or ROOT folder.

The Title name is the same as the Object name. The Subtitle is the same as the instance name.

A filename is the combined title:subtitle. An objectname is the combined object:instance.

UNIFORM RESOURCE LOCATOR

To make interfacing with other filesystems easier across inter/intranets Grail has adopted a naming system that is compatible with UNIX and the URL (Uniform Resource Location) syntax. To access local files you can use the prefix "local:","file:" or no prefix at all. To access non-local files you must use the prefix "nonlocal:" or "ftp:". Grail also recognized "user:" as a synonym of the user's base folder.

TOC


The Anatomy of the File

BY | Lewis Sellers lsellers@usit.net

The Grail file is a composition of three parts: The Binding, The Associative Branch, and the Data Branch. Depending on your policy settings, a file containing 1-byte of data could take up only 200 odd bytes or so, including everything. Or, if speed is of the utmost concern, you can, on a file by file basis, have the file take up a little more overhead but have much better response by isolating each section on sector boundaries.

	File Structure Illustration
	 ___________________
	| BINDING           |
	|                   | ------
	|___________________|     | |
	                          | |
	 ASSOCIATIVE BRANCH       | |
	 _	 ___________________   | |
	|	| FILEMAP           |<-  |
	|	|                   |    |
	|	|___________________|    |
	|	 ___________________     |
	|	| ASSOCIATIVES      |    |
	|	|   System          |    |
	|	|   Application     |    |
	|	|   User 1          |    |
	|	|   User 2          |    |
	|	|        .          |    |
	|	|        .          |    |
	|	|        .          |    |
	|	|   User n          |    |
	|	|                   |    |
	|_	|___________________|    |
	                            |
	 ___________________        |
	| DATA BRANCH       |<------
	|                   |
	|___________________| 
BINDING

The binding is a static structure that exists only in a folder (a folder being a list of bindings) and that describes the file. In other systems, it would be called a directory entry. Details of the binding structure are provided later in the document.

FILEMAP

A filemap stores information describing how the file maps onto the device.

ASSOCIATIVES

The associatives are sections of the associative branch not including the filemap, which are the system associatives, the application associatives and potentionally several user associatives.

DATA

The data branch very simply contains the data of the file.

TOC


The File Heirarchy

BY | Lewis Sellers lsellers@usit.net

Grail is not as reliant upon the "everything is a file" concept as UNIX is, but it has a definite hierarchy.

What is filespace and what does it look like?

File-space is the term used to designate any place where a file can be stored, whether it be on a hard-drive, a floppy, a CD-ROM, or those again remotely. The collective term to refer to all such devices except modems and network cards are file-devices. This includes the aforementioned floppies, hard-drives, CD_ROMs and tape-units.

File-space in Grail is hierarchical in nature, starting with the ROOT, the sub-root, folders and then files.

There are in general about ten (10) file types for Grail, which are: ROOT, DRAWER, VIRTUAL DRAWER, FOLDER, ARCHIVE, SYSTEM, OBJECT, DATA, TEXT, and LINK.

The ROOT is the very top-most structure on all of your filespace devices. All of the essential files that GRAIL requires to functions are stored here, including the core itself. Within the root filespace there are folders containing secured information about multiple users, filespace device objects and, rather importantly, the sub and virtual roots.

[ed: redo]

ROOT FILESPACE

EXAMPLE FILE-SPACE MAP ROOT | |------------------|------------------------| DRAWER DRAWER DRAWER | | | FOLDER FOLDER FOLDER FOLDER FOLDER FOLDER LINK FOLDER LINK FOLDER---FOLDER---FOLDER FOLDER ROOT |

|- Core |- Session State File |- Virtual Memory Swap File |

|--| drawers |

|--| virtual drawers |

|- /Help/ | All Grail help files reside here. |

|__/User/ |- NULL/ |- Default/ |- Supervisor/ DRAWER

A drawer is a special folder which contains additional information allowing it to address other drives or drive partitions.

VIRTUAL DRAWER

Same as a drawer, but references folders on remote computer systems.

SPECIAL USER FOLDERS

There are a few special folders that exist in the root space that are not drawers or virtual drawers. These are normal folders, but with predefined special purposes.

One of these is the User BASE Folder, which starts at "/User/". Each user account has it's defined base folder which resides within these folder. Within this folder are all the subfolders holding specific information pertaining to them that they can change. All files within the base folder however can not be changed except by the Supervisor account.

The base folder for supervisor mode is always /User/Supervisor/. There are also always /User/NULL/ and /User/Default/.

Folders that you will find in a Base Folder are: "Command Interface", "Redirection", and "Authorization". The Command Interface defines all the folder links used by the command interface of your Metaphor. Authorization holds your passwords and voice verification, etc. Redirection is a little similar to the Command Interface, in that it contains links almost exclusively.

Temporary Folder

Mail Folder

Fax Folder

Hermetic Folder

Mail Folder

News Folder (USENET)

Script Folder

Files that you will find are "User Profile".

USER://

You can use the special reference USER:// to refer to a users BASE folder.

HOW DO (COMMERCIAL) APPLICATIONS FIT INTO THE FILESPACE HIERARCHY?

Excepting of course the special circumstances where you are talking about upgrades or filesystem device drivers, all sets of objects and data files grouped as a distinct applications typically have their own folders and sets of folders. New applications should not ever mingle with others (unless they are upgrades) nor ever place themselves into the ROOT filespace.


TOC

Context Overview

BY | Lewis Sellers lsellers@usit.net

SUPERVISOR USER RESOURCE FILE

[min: For a very very long time this was an enormous structure known as the PNF Policy/Navigation File, but there were huge revisions for 1.0 and the structures were broken up.]

This file resides in root space. It contains a list of all the user accounts under Grail. All accounts are situated in below the /user/ folder. See URF for more information.

As you can tell, HTML has had some impact on the design of the entire file system. Originally I came up with the metaphor concept, and then created a file system that would easily serve it before I ever had full internet access. Rather to my surprise, HTML and my Metaphor/FS had much in common in the way they viewed the world. I have tried to further change the Metaphor/FS so as to be extremely friendly to concepts of abstract visualization inherent therein.

The policy information in the file is read into memory, and all changes are echoed back to the file.

The SURF resides only in the top-level of ROOT space, and always has the same name "Supervisor User Resource File". Only the Supervisor (ie, parent) has the right to directly change anything in root space. Other users can not even directly look into the root space and see what files exist there.


TOC

A File Systems Overview

BY | Lewis Sellers lsellers@usit.net

User BASE Folder

For security and ease of use within family and educational environments, Grail is capable of having several distinct configurations for various persons. The hardware setups all remain the same, but each user can have separate core-up parameters and folders available to them.

The way this works is that when Grail starts, after having gone through the Supervisor User Resource File, it looks through the users in the /Users/ folders to see if there is more than one of them there. If not everything continues as normal. Otherwise it switches to what is called the NULL User. That is, it loads it's user data partially from an internal structure in the core and this users Task Automatic Load is the Metaphor Program __USER_VERIFICATION which resides in root space (naturally). The supervisor can alias in different custom object for this, but the default one that comes with Grail very simply presents a conservative but pastel screen requesting your user name, and whatever means of access authorization you require. Usually this is a password.

The folder is an example list of the folders in the /Users/ folders.

/User/NULL/

/User/Supervisor/

/User/Default/

/User/Lewis Sellers/

/User/Susy/

/User/Sissy/

/User/Michelle Sellers/

________________________________________________________________________________

User Account Resource File (UARF)

_______________________________________________________________________________

In each users base folder, there is a file called the "User Account Resource File". They can only be edited by an application while you are running as a Supervisor (/User/Supervisor/).

Illustration
User
.-----------------------
| User type             |
|_______________________|
Binary Items
.-----------------------
| DOB                   |
| POB                   |
| Time                  |
| Location              |
|_______________________|
Policy Items
.-----------------------
| Policies              |
|_______________________|
Text Items
.-----------------------
| Object Automatic load |
| Task Automatic load   |
| Script                |
|_______________________|
USER TYPE

There are three types of users as defined by Grail: The Supervisor, The Normal User, and the Child User.

The supervisor user account is not limited in any fashion, and uses the general global default files, etc. Only someone with supervisor status can change, delete or create other user accounts. Also, only they have direct access to the bulk of ROOT space. All others are always restricted to using DRAWER space and their folders. There is only one Supervisor account. A log is kept in ROOT space of failed attempts to gain supervisor status. This user type is sometimes known as "parental control".

The normal user account, the one most often used, is known technically as an Explicitly_Restrict account. It is for the family, friends, co-workers, and even the primary user. It has also the same resources as the Supervisor, except that access to ROOT space is denied them, and the Supervisor can explicitly restrict folders from them, or limit free space in a drawer or folder. Each account has it's own separate settings, so you can customize it without affected others on the machine.

A child account is technically called a Restrict_Unless_Explict or Pariah* account. This is for children or running demos in stores, etc. By default they are denied access to everything. The supervisor must explicitly declare what folders they can use and how much space they get. As said, in the real world, this is typically the status given to family and neighborhood kids so they can play a few games or educational programs without destroying all your work or viewing R-rated or better materials. Also good for Grail-based BBSes.

As an aside, there is also a NULL User Account. It is denied everything and automatically runs a function that asks which user you wish to log in as and its passwords. The supervisor can change this and thus customize the authorization program.

And finally, there is a Default User Account (/User/Default/). You are forbidden from running as user Default, but the Supervisor and setup a User Account Resource File for them. Their Binary Items, Text Items and Polices are used before the user you log in as. This is just a handy thing to be able to do.

*For Gary, The Orion Overlord. R.I.P.. :-)

BINARY ITEMS

Date of Birth

UTCAD_TIMECODE DOB

Point of Birth

ULCLL_LOCATIONCODE POB

Time

UTCAD_TIMECODE Time

Location

ULCLL_LOCATIONCODE Location

TEXT ITEMS

OBJECT AUTOMATIC LOAD

This section is an asciiz13 listing of all the objects that Grail should load in automatically after core-up. This operation occurs directly before the task autoload operation. Each object is verified and loaded in the order it is listed in the section. If any object can not be loaded a null object (see __OBJECT.NULL) is created in its place.

This is a list of all the objects that are originally listed in the object autoload:

GRAPHICS

3DGRAPHICS

GMIDI

DIGITALAUDIO

FMAUDIO

VISUAL

MONITOR

CURSOR

TEXT

OLEFACTORY

KEYBOARD

JOYSTICK

MOUSE

LIGHTPEN

TABLETPEN

VR_ABSTRACT

VR_HUMAN

TASK AUTOMATIC LOAD

METAPHOR

POLICIES

You can change the operating policy of all the CORE functions through the User Account Resource File.

[ed: reformat these!]

OBJECT.Function Auto-Null

If this is flagged on, then any request for an object that fails causes a NULL object to be created automatically and a 2 to be returned.

SYSTEM.Optimization switch

This sets the global switch CORE_OPTIMIZATIONS. If it is 0, then the operating system should take advantage of every performance trick it knows of... mainly things related with aligning data. This setting is usually more memory hungry. For less powerful machines, you may need to drop this down to 1. By default it is 0. This is usually set by a Metaphor program.

SYSTEM.Optimization_Get

Returns the SYSTEM.Optimization.

SYSTEM.System_Class

"Personal Computer"

"Workstation"

SYSTEM.Processor_Name

"intel 486sx""

SYSTEM.Platform_Name

Allocates memory and copies a string into it. The handle is passed back. Currently recognized platforms are:

"IBM-derived PC"

"APPLE-derived Macintosh"

OBJECT.Language langcode

This function tells the operating system which languages the personnel prefers to use. An application can then query the OS itself instead thus not having to pester the end-personnel to repeatedly re-answer a simple question. Also, the driver functions use the policy language to determine which set of text info to load in for use by the personnel.

You can have any number of languages listed that you want. Generally you create a list of the languages that you can read in the order of your preference or proficiency. The first language in the list is assumed to be your primary or original language.

The langcode itself is a 32-bit number that is directly computed from the ASCII letter codes internationally assigned to each language. English for instance is eng. Thus the langcode sequence is 97 + 110 +103 + 0, and the langcode itself is 6778465. (Ie, 97 + 110*256 + 103 *65536 + 0*16777216)

Below is a sample list with a couple langcodes resolved.

ara Arabic chr Cherokee chi Chinese dan Danish egy Egyptian eng English 6778465 esk Eskimo esp Esperanto fin Finnish 7235942 fre French gae Gaelic (Scots) ger German gre Greek haw Hawaiian heb Hebrew iri Irish ita Italian jpn Japanese 7237738 lat Latin rus Russian swe Swedish tib Tibetan
CODELANGUAGELANGCODE
apaApache
Language_Get

Gets the current language preference (langcode).

OBJECT.Filter debug, info, parameter

Settings the filtering aspects for loading objects into active memory. By setting any of these you cause it to be stripped from the object at load and all pointers directed to a NULL. If you're having problems with running out of memory for a program, filter everything.

OBJECT.Filter_Get

Returns the debug (EAX), info (EDX) and parameter (ECX) filter settings.

__VMMU.Size swap_size

Defines the size of the virtual memory common swap file. This value only takes effect after the next __VMMU.Create. Though it does accept any value, currently the size is rounded up to the nearest megabyte.

__VMMU.Size_Get

Returns the size of the swap file.

Filesystem_Names preference

Defines whether you prefer to use ASCII or UNICODE for text. The default right now is ASCII, but it will be changed to UNICODE just as soon as we familiarize ourselves intimately with UNICODE.

__FS.Defrag switch

This policy setting controls how Grail reacts if you try to create file on a sub-root that has insuffficient filespace. A switch of 0 means simply report it as an error. A switch of 1 means do a __FS.Defrag first, then check again.

__FS.Overwrite

overwrite 0=no 1=if exists? 2=only if newer

__FS.CreateFolder

create folders if need be?

__FS.

0=kill pointer 1=zero data 2=security delete

__FS.DeleteFolder

Allow deletion of folder (and files within) only:

0 when empty

1 if no other folders are contained within

2 just delete them

__FS.Target

0 USE CURRENT

1 use target

________________________________________________________________________________

Access

_______________________________________________________________________________

Access is granted or restricted in Grail either on a folder-by-folder basis or on a folder an child subfolders inclusive basis.

Grant_Folder

Access is granted to the folder specified.

Restrict_Folder

Explicitly declares a folder that is not accessable by a personnel.

Grant_File

Restrict_File

Grant_Folder_Specifically

Restrict_Folder_Specifically

Grant_FreeSpace

This is only used with Restrict_Unless_Explict, and limits the pool of....

________________________________________________________________________________

Security Authorization

_______________________________________________________________________________

All user authorization programs must reside below /User/Authorization/. All authorizing files (passwords, voice IDs) should reside in the users BASE folder in the Authorization/ subfolder.

/User/NULL/

/User/Authorization/

All plaintext passwords should reside in the file "Plaintext Password". All encrypted passwords should reside in "UNIX Encrypted Password".

If you wish to use comparison voice-authentification to gain access to a user account, the file name should be "Voice Comparision" and the filetype should be Audio/AU.

Group

User

age

_____________________________________________________________________________

P O L I C Y F U N C T I O N S

_____________________________________________________________________________

Policy functions sets switches and flags that determine some global aspects of the functionality of the entire operating system. Typically these changes are shadowed and/or saved into the Policy / Navigation File (PNF) which resides in the root of the boot device.

HARDWARE

Hardware policy entries are unique on the system. That is, they are the same for every profile, account or user that uses the computer. Only the supervisor can change them. They are grouped by object class and instance. Each can use a set of unicode/ascii text parameters to set different aspects of a device object.

__POLICY.HARDWARE_Add ptr_OBJECT.name, ptr_instance_name, ptr_item_line

Only while in the supervisor profile mode.

__POLICY.HARDWARE_Get ptr_OBJECT.name, ptr_instance_name, ptr_item_prefix

Only while in the supervisor profile mode.

__POLICY.HARDWARE_Delete ptr_OBJECT.name, ptr_instance_name, ptr_item_prefix

Only in the supervisor profile mode.

__POLICY.HARDWARE_Purge

Only in the supervisor profile mode. Checks to see if the drivers specified actually exist, and deletes all nonsensical entries.

RESOURCES

Defines how various resource are to be used.

__POLICY.RESOURCES_Add ptr_group_name, ptr_grouptype_name, ptr_item_line

__POLICY.RESOURCES_Get ptr_group_name, ptr_grouptype_name, ptr_item_prefix

__POLICY.RESOURCES_Delete ptr_group_name, ptr_grouptype_name, ptr_item_prefix

__POLICY.RESOURCES_Purge ptr_group_name

Removes all entries for the specified group.

OBJECT

Qualifies parameters or sets defaults used by objects.

__POLICY.OBJECT.Add ptr_class_name, ptr_instance_name, ptr_function_name, flag

__POLICY.OBJECT.Get ptr_class_name, ptr_instance_name, ptr_function_name, flag

__POLICY.OBJECT.Delete ptr_class_name, ptr_instance_name, ptr_function_name, flag

__POLICY.OBJECT.Purge ptr_class_name, ptr_instance_name

PROFILE

Manages user profiles.

__POLICY.USER_Create ptr_form

STRUCT

db usertype

db ?

dw age

ptr ptr_name

ptr ...

ptr ptr_access

dptr access_length

ptr ptr_authorization

dptr authorization_length

STRUCT END

usertype=

supervisor

explictly_restrict

restrict_unless_explict

age=

1-n

0 not-relevant

-1 child (innocent)

-2 youth

-3 young adult (provisionally adult)

-4 adult

__POLICY.USER_Revise

?

__POLICY.USER_Modify

Modifies the current profile.

__POLICY.USER_Delete

For security reasons you can only delete your own current profile. When this happens you are automatically thrust back by the core to a NULL Profile just as if you have just got core-up. You can not delete the supervisor profile.

_____________________________________________________________________________

S E S S I O N

_____________________________________________________________________________

__SESSION.Save

Does a complete save of every single thing in the __MMU list after it saves the __MMU list itself. The file structure is very simple. The file is always called 'Grail_CoreImage' and it resides in the root space of the primary device along with the Policy / Navigation File. It begins with:

STRUCT d.32 build ;the GRAIL core build d.32 timedate ;a time date stamp STRUCT END Then follows a dump of several internal pointers, then a dump of the complete __MMU list, followed, in sequence of their appearance in the list, a memory dump of each of the memory blocks.

This function is used by some Metaphors for quick resume ability. Others sometimes use it for emergency session resumes, by invoking it every 15 or so minutes.

This function is also known as a CORE IMAGE SAVE.

__SESSION.Restore

The inverse function of COREIMAGE save. It overwrites the current session in favor of the previous one assuming the build versions are identical. Do not attempt to write your own session save routines. Internal changes will almost be promised to result in failure.

This function is also known as a CORE IMAGE RESTORE.

_____________________________________________________________________________

COMPRESSION

_____________________________________________________________________________

Data and associative branches can have automatic on-disk compression if so flagged. They are, it might be mentioned, independent of each other. There is an ASCII associative to name the compression type, but that can almost be ignored and only the flag used since only one compression type is incorporated directly into the operating system. As of this writing it's a fast variant of huffman.

You must explicitly compress a file on a device. When reading it the data is automatically decompressed for you. It is only permanently decompressed by writing to the file or explicitly issuing a command to decompress it.

As you know, compression and decompression of files is built into and the Grail Operating System. By default you would use the core-compiled generic-compression and generic-decompression routines which are accessed via the __COMPRESS and __DECOMPRESS objects.

It should be made clear however, if you missed it when looking through the File System document, that Grail, true to it's nature, is not shackled to any single de/compression routine. You are guaranteed the generics will always be there, but third-parties can create and distribute any other new software they like.

Say for instance Stacker, the premiere company for de/compression software, decides they'd like to help the Grail consumer out by providing the absolute best technology available. They could create a free-ware __DECOMPRESS object instance to handle any file compressed with their technology. They would then also make a shareware and/or commercial __COMPRESS object instance. While you'd need to buy their product to compress using their technology, anyone with the free decompression object could later on use any files so compressed.

What's the point? Grail simply provides the framework and workable objects for inclusion with it. The compression/decompression that comes with Grail is good, but there is no way for it to beat that of Stacker and the techs. Even the juggernaut Microsoft apparently though so at one time.

I whole-heartedly encourage for-profiet companies to develop plug-in technology to enhance grail, especially when some of their basic functionally can be had by the end-consumer for free or at a negligible cost.

__COMPRESS.FileEstimate ptr_refID

Returns the estimate of compression results as well as the file's original size. For example:

(FileSize,CompressedSize) = __COMPRESS.FileEstimate "test_file" __COMPRESS.File ptr_refID

Compresses a file with the current policies preferred compressor. It then flags the file as having a compression policy and as being compressed, and adds the instance name of the compressor to it's pre-associative branch.

__DECOMPRESS.File ptr_refID

This permanently decompresses a file and sets it's flags to non-compression. You can of course a read compressed file without doing this since all accesses to the file will automatically decompress portions of it to memory. Note that __DECOMPRESS and __COMPRESS are separate object classes for very specific commercial reasons (ie, a company can give a decompressor away for free but charge for the compressor).

_____________________________________________________________________________

E N C R Y P T I O N

_____________________________________________________________________________

The encryption of an object and the encryption of a file are separate issues. __ENCRYPT and __DECRYPT are separate object classes.

__ENCRYPT.Object ptr_refID, instance, encryption_stream_handle

Uses the current policy encryption object class to encryption an file that is an object

__DECRYPT.Object ptr_object, decyption_stream_handle

This decrypts the code and data section of an object that is already loaded into memory. This function is not meant to be called by other than the operating system. It is called after an object is loaded but before the creation function is executed.

__ENCRYPT.File ptr_filename, encryption_stream_handle

Encrypts a file.

__DECRYPT.File ptr_filename, decryption_stream_handle

Decrypts a file.

EXAMPLE USER RESOURCE FILES

"And fools shine on..." brother caine

Resources

[Control] Root= Core= Session= Swap= [Image] Core= Application= [Object]

Device=

Platform=

Script=

[Plaintext]

ASCII/TXT= ROOT/Text_Viewers/VPRO

UNICODE/TXT= ROOT/Text_Viewers/UNIVPRO

Document/GRAY= ROOT/Text_Viewers/GrayReader

Document/RTF= ROOT/Text_Viewers/Word7_Reader

Document/HTML= ROOT/Internet/Netscape/Netscape

[Data]

Image/JPEG= ROOT/Image_Viewers/ACDSEE/ACDSEE15

Image/PNG= ROOT/Image_Viewers/ACDSEE/ACDSEE15

Image/GIF= ROOT/Image_Viewers/ACDSEE/ACDSEE15

Image/TGA= ROOT/Image_Viewers/ACDSEE/ACDSEE15

Image/PCX= ROOT/Image_Viewers/ACDSEE/ACDSEE15

Image/TIFF= ROOT/Image_Viewers/ACDSEE/ACDSEE15

Image/Native= ROOT/Image_Viewers/ACDSEE/ACDSEE15

Image/MPEG1= ROOT/Movie_Players/MPEG1/MPEG1

Image/MPEG2= ROOT/Movie_Players/MPEG2/MPEG2

Image/QuickTime= ROOT/Movie_Players/Apple_QuickTime/QuickTime_Player

Image/FLICK= ROOT/Movie_Players/Trilobyte_FLICK_Player/FLICK_PLAYER

Document/WORD= ROOT/Text_Viewers/Word7_Reader

[Alias]

__USER_AUTHORIZATION= ROOT/Authorizations/Babalyon5_Authorization

[Object Autoload]

GRAPHICS

3DGRAPHICS

GMIDI

DIGITALAUDIO

FMAUDIO

VISUAL

MONITOR

CURSOR

TEXT

OLEFACTORY

KEYBOARD

JOYSTICK

MOUSE

LIGHTPEN

TABLETPEN

VR_ABSTRACT

VR_HUMAN

[Task Autoload]

METAPHOR

[Type]

UserType= Supervisor

Maturity=Adult ;28yrs

[Authorization]

Name= Lewis Sellers

Identity= herekittykitty

Authorization= ROOT/Authorizations/Lewis_Sellers

Verification= ROOT/Authorization_Verifications/VoiceVerify

[Alias]

Metaphor

ROOT/Metaphors/Natural_Landscape

[Task Autoload]

METAPHOR

******

;Lewis_Sellers

[Type]

PersonnelType= Supervisor

Maturity=Adult ;28yrs

[Authorization]

Name= Lewis Sellers

Identity= herekittykitty

Authorization= ROOT/Authorizations/Lewis_Sellers

Verification= ROOT/Authorization_Verifications/VoiceVerify

[Alias]

Metaphor

ROOT/Metaphors/Natural_Landscape

[Task Autoload]

METAPHOR

****************

;Susy

[Type]

PersonnelType= Restrict_Unless_Explict

Maturity=byDOB

DOB=13/7/91 ;age 4

[Authorization]

Name= Susy Q.

Identity= Susy

Authorization= Sissy

Verification= /Authorization_Verification/PasswordCompare

[Access]

Grant_Folder= /Drive3/Tetris

Grant_Folder= /Drive3/DOOM2

Grant_Folder= /Drive3/Pooky's_PlayHouse

Grant_FreeSpace= 10MB

[Task Autoload]

/Metaphors/Cat_Land

*****************

;Michelle_Sellers

[Type]

PersonnelType= Explicity_Restrict

Maturity=Adult ;Age 23

[Authorization]

Name= Michelle Sellers

Identity=Missy

Authorization= /Authorizations/Michelle_Sellers

Verification= /Authorization_Verification/PasswordVerify

[Access]

Restrict_Folder= /Drive3/Borland_C++

Restrict_Folder= /Drive3/Watcom

Restrict_Folder= /Drive3/Grail_R&D

[Task Autoload]

/Metaphors/Natural_Landspace

_____________________________________________________________________________

B I N D I N G

_____________________________________________________________________________

This is extremely important. Listen up. A binding is the essential structure which binds the data and associative branches together. The bulk of the data in folders is simply a long list of bindings. This is true of the root, drawer and virtual roots as well.

The binding consists of a refID (32-bit dword on Intel processors), a series of 8-bit flag groups, BRANCH offsets/lengths and timedate data. There is also a "BIND" at the beginning of each for verification. A file is considered erased if it's "BIND" key-word is missing. By convention, you permanently erase a file by nullifying out those four bytes. Also, you can change it to "bind" (lowercase) which technically stills means the file is erased, but this allows routines later on to be run that might be able to reconstruct your file.

This is the file binding structure in GA (Grail Assembler) notation:

CLASS STRUCT FF_BINDING

ascii <BIND>

d.8 filespace_bitwidth ;bitwidth of file pointers in 2^(n-1), usually 6

dbit.8 format

1 series ;series or vol/no?

dbit end

dbit.8 type

4 primary

4 sub

dbit end

dbit.8

1 token

1 temporal

2 security

1 supervisor

1 application

dbit end

fsdptr refID ;usually 32-bits

dbit.8 log

1 accesses

1 error

1 history

dbit end

dbit.8 access

1 read_only

1 write_only

1 archived

1 copyright ;permit the file to be copied?

dbit end

dbit.8 change

1 copy ;0=original 1=copy

1 upload ;1=has been transferred "up"

1 download ;1=has been downloaded but not yet opened

dbit end

dbit.8 policy

1 use_compression ;shall we do a decompress when accessing?

1 encrypt ;access blocked by encryption?

1 contiguous ;streaming?

1 static

1 emulation

1 mirroring

1 caching

1 speed ;size/speed

dbit end

dbit.8 policy_check ;inverse check

dbit end

dbit.8 status

1 compressed? ;shall we do a decompress when accessing?

1 encrypted? ;access blocked by encryption?

1 complete? ;file only a partial? (error or downloading?)

1 corrupt? ;DO NOT CHANGE!! File has problems.

1 viral?

1 contiguous?

dbit end

dbit.8 status_check ;inverse check

dbit end

STRUCT data

dptr length

dptr space

dptr start

STRUCT END

STRUCT associative

fsdptr length

fsdptr space

fsdptr start STRUCT END STRUCT count d.32 accesses d.32 upload d.32 download END STRUCT series d.32 last d.32 no STRUCT END STRUCT revision d.32 limit d.32 no STRUCT END STRUCT fragment d.32 fragments d.32 no STRUCT END UTCAD_Timedate create ;created UTCAD_Timedate modify ;last modified UTCAD_Timedate access ;last accessed UTCAD_Timedate event d.32 sort d.32 Security_ID d.32 mirror_no d.8 lock STRUCT END

FILESPACE BITWIDTH

The filespace value indicates the size of all offsets used in the BINDING and ASSOCIATIVE BRANCH. Normally this is 3, which indicates a 64-bit or 18,446,744,100,000,000,000 (or 18 pentillion) byte file space. For smaller devices, such as floppies and IOMega ZIP drives, you'd use the 2 type which is a 32-bit or 4 gigabyte filespace. The FILESPACE_WIDTH is the bitwidth of the filespace expected by the file starting at 8-bits and using a 2^nth power to compute all that comes afterward. There is some expandibility for the future as you can see from the table below:

Width Actual Bitsize 0 8 1 16 2 32 3 64 <-- default 4 128 5 256 This is used to verify that the file is using the same bitwidth as the current filesystem. You can, I might mention, have one device using 32-bit filespace and one using 64-bit. As a file is moved, the file structure is appropriately modified.

FORMAT.SERIES

If the series flag is 0, then the series data is one number. If it is 1, then data is two equal bitwidth components.

TYPE.PRIMARY

There are 10 binding types.

0 NULL 1 root (supervisor area) 2 file drawer 3 folder 4 archive folder 5 file 6 system file 7 object file 8 binding link 9 virtual file drawer 10 package TYPE.SUB

System File

1 Core 2 Saved Session Image (rapid resume) 3 Global Swap File 4 Supervisor User Resource File 5 User Account Resource File Object File

There are four types of objects:

0 Device-dependant Object (device object) 1 Platform-dependant Object (object) 2 All-platform Script (the only one with a non-binary data branch) (script) TOKEN

This allows you to create a simple stand-in token file for a file that is not currently available locally. Refer to the section on tokens for more information.

A token file is one in which only the binding and part of the associative branch are valid. This type of file is a place-keeper for non-local files that may exist on LAN (Local Area Network) or WANs (Wide Area Networks) but have not yet been transferred. Suppose you log into ftp.cdrom.com and do a directory of /pub. Under Grail you would have created a virtual root containing /ftp.cdrom.com/pub/ which would be filled with tokens of all the files shown by your dir or ls command.

Each binding has a bit field called token:

0 non-token

1 empty token

A token file uses the data branch to store a simple structure containing the date at which the token was created and a formal URL where the complete file may be found.

CLASS STRUCT

UTCAD_Timedate Token

STRUCT END

URL: ;label for NULL-string

TEMPORAL

0 permanent

1 temporal

A temporal file is one that is tagged with a life-expectancy. When this peroid is at an end, the file is automatically deleted. The peroid of expiration may be of three flavours:

Demand Only

You may explicitly purge a specific temporial file, all temporials from a folder or all temporials globally.

Low Resource

A forced Demand Only.

Expiration Date

A UTCAD timedate either expressly stated or derived from a life-expectancy. The GUTC resides in the binding event.

SECURITY

SUPERVISOR

Any file flagged as supervisor is only directly accessable via the Supervisor Account or internally by the core.

APPLICATION HEAD

refID

The 32-bit refID is the actual value the Grail FS uses internally for handling/scanning files. As there is the possibility for over 4 BILLION UNIQUE files per subdirectory in Grail (coupled with it's lower need for seperate files due to the associative branch and it's refID latency policy [give up old used refID's only during a PURGE or when 4gb-1 refIDs have been used]) the possibility of confusion locally is almost nonexistant. The file name, etc are looked up only when asked for thusly.

Using 32-bit numbers to reference each file (instead of long names) also cuts memory overhead.

A refID sequence consisting solely of a single NULL points to the ROOT. If the sequence has one element then it points either to a sub-root, a system folder or a system file. System files and system folders always have the same refID, so yes, this means you can always directly reference a ROOT system file without having to do a name-string lookup.

refID bitwidth depSTRUCT END on the filespace pointer size, thus while usually 32-bits, you may also encounter 64-bit refIDs on some systems.

It didn't start out this way, but in an order to have extremely long filenames I moved them to the associative branch. In order to reference a file I created the ideal of using unique 32-bit reference ids for files (or folders). You would reference a file using a string of these 32-bit refIDs denoting the folders, subfolders and then the file you were talking about. It was about this time a few months ago that I got my first true internet account... and lo and behold I encounter URLs and the DNS! Suddenly everything meshed and became very clear. So yes, Grail in effect now uses a DNS/URL similar file naming system. All files use a string of refIDs, which you can lookup through folder and filenames through the __FS.FileLookup function much like a DNS lookup.

A DNS is composed of 4 8-bit numbers, though, I might mention and does not reference actual files, while each element in the Grail FS is 32-bits currently. The bitwidth of the refID is usually the same as the architecture of the machine it is running on, I might mention. You can set the default to other though. For example, most Intels currently have 32-bit pointers and a 32-bit filesystem. With the bigger hard drives and DVDs coming out though, you might have 64-bit refIDs.

Grail's FS and core are designed with the idea in mind that at some point it may run on 32-bit, 64-bit, 128-bit, 256-bit, etc systems or devices.

LOG

If any of the loggging bits is set, then each access of a file will cause information to be added to it's associative file under the approriate...

Accesses

Errors

History

EMULATION

Grail provides some limited ability to interface with other older filesystems such as DOS FAT. This is mainly intended for accessing images and data from soon-to-be-old pre-DVD CD-ROMs (~500 to 700kb), etc. To access these files you must first have GRAIL automagically create bindings for them that link to the old files. These new bindings have new associative branches but point to the same old data file as the data branch. At this point, you should notice that neither the binding, associative branch or data branch must exist on the same physical disk....

__FS.EMULATION_

CACHING

If no, then the policy is that no disk cache is required for performance reasons. Probably the file will be read completely into memory.

SPEED

Favour Speed over Size? Not currenty used.

USE_COMPRESSION

Is the file flagged that it should be compressed for best performance? When modifying files, they are typically automatically uncompressed so that the constant decompression/uncompression routines don't bring the system to a crawl. Occasionally it's good to have a program search through your files compressing anything that should be. Simple housekeeping.

ENCRYPTED

This file is encrypted.

COMPLETE

If not set, then file is assumed to be from an aborted download, or is CURRENTLY being downloaded.

READ_ONLY

Grail will not allow the (data branch of the) file to be written to or changed.

ARCHIVED

Is this file part of an archive? thus possibly compressed and encrypted?

VIRAL

Flag this if suspect.

CORRUPT

A very stern read-only flag for disk managers.

1 compressed? ;shall we do a decompress when accessing? 1 encrypted? ;access blocked by encryption? 1 complete? ;file only a partial? (error or downloading?) 1 corrupt? ;DO NOT CHANGE!! File has problems. 1 viral? 1 contiguous? COMPRESSED?

Is the file currently compressed?

CONTIGUOUS?

Is the file now currently contiguous? Slightly different routines are used when non-contiguous and contiguous.

STREAMING?

Essentially, if this flag is set, we are saying that the file is of a nature where it's data is streamed-out at high speed and it should, if at all possible, be physically contiguous.

STATIC

COPYRIGHT

Permit the file to be copied? By default you can copy any file, however, if this is set to 1, then Grail copy functions will not work. This does not mean there are not ways to get at it, just that it is harder.

SECURITY

Privilege is either none/personnel (0) or OS (1). Among other things, any file that is privileged is only accessable if you are the Supervisor.

Should the file be secured from corruption by other programs? If this flag is set, then when the application is started up several things will happen. One of which is that all memory handle's which are owned by the process will be invisible to all but the core. What this means is that if another program is viral, etc it can not uses the MMU functions to look up what memory is being used for what, and since this list is down in SECURE memory behind CPL0 supervisor pages, it can not be gotten at directly. Other things may also be used to protect the program later on.

COPY

Is this the original or the copy?

UPLOAD

Has this file been copied remotely?

DOWNLOAD

Has this file been downloaded, but as yet not "used" or looked at?

COUNT.ACCESS

How many times has the file been accessed?

COUNT.UPLOAD

The number of times a copy of a file to a non-local area has been made.

COUNT.DOWNLOAD/REFRESH

The numer of times this file has been retreived from a remote location. This may sound strange at first, but consider it a refresh count. If a file of the same name, etc already exists here, then it will inherent this count +1.

ASSOCIATIVE BRANCH

length

the length of the assc branch

space

the filespace actually reserved for assc

start

the direct linear starting address of the assc

DATA BRANCH

SERIES

You can specify that a file of the same title and subtitle is part of a series if you wish. Thus, for instance, you could have 213 nice PNGs of your favourite cat and use this to specify which they are in the series. Also useful for publications or newsletters. Series can be represented as a single series number or broken up into a volume/number pair. For example: "Discover:THE WORLD OF SCIENCE;16,12".

Whether series is a single or paired number depends on the format.series setting. The vol/no format is 16 bits each part. There are two series variables in a binding. Series.Last denotes the logical last number in the series. Series.no denotes this files number in the series.

This always uses d.32, thus giving a maximum series limit of 4,294,967,295. The series number 0 is special, and is taken to mean the either that the series number should be ignored or that series is not used.

REVISION

You can have multiple backup revisions of a document available. That is, you can specify that a certain document you are working on should allow 10 revisions of itself to exist at a time. Every time you save the document (or autosave it) a new version is created and, if there at more than 10 versions alread in existance, the oldest ones are erased.

There are two revision variables. Revision.limit is the maximum number of revision ofthis file allowed. Revision.no is the revision number of this current file.

The revision number can go up to 4,294,967,295, at which point it loops around. It starts at 1. A revision number of 0 means to ignore revisions.

FRAGMENT

Occasionally your file may be larger than the capacity of the medium you are trying to store it on. This most often happens with the now extremely aged floppy disks still in use.......

SORT

A kindred variable of the refID. Sometimes SORT and refID in a folder are identical.

This is for file sort classes to take advantage of.

SECURITY ID

Default of 0. Every user gets one..............

LOCK

If lock is not-zero then the file is currently busy being modifyed by another process. Check again later.

________________________________________________________________________________

FILESYSTEM TRANSLATION

_______________________________________________________________________________

Need to translate some old DOS files into GRAIL?

_______________________________________________________________________________

_______________________________________________________________________________

One of the very first things you will do with Grail after booting up it's install program is to create a Grail filesystem. It may reside in it's own partition or be statically embedded in a DOS/WIN95 FS. It all looks the same to Grail.

If you were to install Grail on the system I'm using now, it would automatically generate the following drawers.

/QUANTUM ELS170A 4.40 166317883587 142mb VFAT/

/QUANTUM ELS170A 4.40 166317883587 20mb PERMANENT_FILE/

/MAXTOR 7546AT EA7X3636 C608NAJS 249mb VFAT 1/

/MAXTOR 7546AT EA7X3636 C608NAJS 235mb 2/

/MAXTOR 7546AT EA7X3636 C608NAJS 40mb 3/

/FDC_1.4mb_Floppy/

/CL50A_2X_CDROM/

Obviously, though descriptive, this is more than a little difficult to read. You can of course rename the drawers to anything you feel is more appropriate. Those drawers with the keyword VFAT are formatted with the newer version of DOS FAT that is included with Window 95. Normally, unless you have a device object installed that will emulate through VFAT, you will be denied access into those particular drawers.

My C: drive has a 20mb permanent file that Grail has erected on it. I have done this as an example. Most computer illiterate people will typically have one large, unpartitioned hard drive. To have them either go through the newbie horror of partitioning it or suffer the added burden of buying a second hard drive specifically for Grail is just not realistic.

To that end, a special program (simple real-mode sufficing) will come with Grail that will allow the computer illiterate choose a certain number of megabytes of hard disk space to be given over to Grail in the format of a permanent DOS file. This is essentially the same kind of setup as the Window swap file. The file has a set, filename and attributes such as:

GRAIL.FS 74,200,218 1-13-95 4:22pm The filename is always GRAIL.FS. The filesize is the file space allocated for that drive. The date is always 1-13-95 and the time 4:22pm. The attributes are always read-only and system. It is marked as unmovable, hidden and is a permanent continguous file.

Grail, in effect pretSTRUCT END the file is a sort of varient of an extended DOS partition. Since, for E/IDE devices, Grail works only with the cylinders we give, we simple compute for it where this DOS file is on the hard drive, pass this start and end clyinders on to it, and it continues on as if it were any partition.

__FS.Initialize virgin

The magic function that sweeps the darkness from the face of the Earth. Queries all filesystem device objects for devices and the various partition/drawer areas. It builds a list in memory of these areas. It then looks for Grail ROOT. If it does not find such it proceeds to create ROOT on the first unused drawer area of the first device of the primary filesystem device object. You can of course move ROOT later on, if you desire.

If ROOT already existed, it of course does not recreate it.

Next, the function begins creating the essential folders in ROOT space, including drawer folders to all filespace areas it has encountered, as the example previously had illustrated.

If the virgin variable is non-zero then we're doing a new installation. With new installations, the multi-OS boot program loads into memory all of the essential required files. Then, on core-up, the core writes them back to root space after it is set up. This is one of the reasons that 4MB is the required minimum to run Grail.

In particular these files include the core, the IDE, EIDE ATAPI, the FDC Floppy, The NULL Authentification......

[ed: fix]

__FS.MoveROOT

__FS.Device device

__FS.Information drawer

Retrieves a header:

STRUCT

d.8 bitwidth

dptr no

STRUCT END

and a list of available FS in the following element structures:

STRUCT

dptr available_filespace

dptr grail_filespace

d.8 type ;0=unknown 1=grail 2=known and changable

d.8 op ;0=grail 1=free 2=resizable.....(fix)

STRUCT END

primary filesystem

grail fs DOS 12 DOS 16 DOS 16 extended WIN95 OS/2 HPFS

__FS.Create device, start, end, root, wipe

This creates a Grail filesystem on the specified device within the specified linear addresses. If the root flag is set, then it also created the filesystem structures for the system root space. How do you get these numbers?

Normally the entire area that is affected is wiped to NULL if wipe is flagged, and then the default structures are created.

**********

HOW DOES GRAIL KNOW WHAT FILE-DEVICES I HAVE?

When a new file system is created, either native or DOS/Grail, the primary navigation file is updated to reference the device and all it's sub-roots. Besides the obvious fill data, a few tests are performed and that data stored: access time, transfer rate, -*etc.

THAT'S NICE, BUT DO I NEED DEVICE DRIVERS FOR MY HARD DRIVE?

Probably not. Grail comes with E/IDE and SCSI device objects compiled into it. You can thus use any such device as your BOOT device. As far as __DRIVER functions are concerned these are critical device drivers just like any other, only they'll always be present and probably at fixed places. If you use a drive that is other than this, then, yes, you'll need more drivers.

Oh, yes, floppy drives (FDC) are supported internally as well.

You can elect to have E/IDE and SCSI drivers other than the internal Grail ones loaded in, btw. This is sometimes useful, depending on the drive in question.

I'M A NUMBER, NOT A NAME!

**********

________________________________________________________________________________

R O O T (SUPERVISOR AREA)

_______________________________________________________________________________

The root is analogous to the drawer at the top of the drawer that is locked. The root is a fairly simple structure in and of itself. It contains a pointer to a drawer structure where ....

RefID is always 0.

STRUCT FF_root ascii <ROOT> d.8 filespace_bitwidth FF_binding binding FF_drawer drawer d.32 refID STRUCT END

__FS.ROOT_Binding

__FS.ROOT_Drawer

________________________________________________________________________________

FILE DRAWER

_______________________________________________________________________________

A file drawer may contain files, folders and folders within folders, etc. Excepting for the root (supervisor area) it is at the top level of all folders. It's data branch describes the filespace device it is associated with and it's partition, if any. In some sense, a drawer is roughly equivalent to a partition. They can only be created or modified by the supervisor personnel.

It's best to have one drawer taking up the full space of each drive, but if you've partitioned or DOS formatted the drive already, you may have several others. Descriptions of all drawers reside in the root. Each drawer has it's own name which is local to your system.

The collection of all the drawers on a physical device (such as a hard drive) is called a cabinet.

CLASS STRUCT FSS_drawer

ascii <DRAW>

d.8 filespace_bitwidth

d.8 transfer_type

d.8 root? ;this file drawer the root?

d.8 drawer_no ;partition #?

fdptr refID ;root refID

FSS_binding folder_binding ;folder used by drawer... first folder

fsptr OBJECT.class

fsptr OBJECT.instance

fsdptr cache ;on-board

fsdptr transfer_rate ;bits per sec

fsdptr access_time ;ns

fsdptr files ;total files in file drawer

fsdptr filespace ;total file space of file drawer

fsdptr freespace

dbit.32

1 grail_fs?

1 exist?

1 non-local?

1 boot?

1 root?

1 See_filespace

1 error_state

1 change_line?

1 changed?

1 removable?

1 removed?

1 mirror?

1 readonly?

1 readoverload

1 writeonly?

2 writeoverload

1 write_protected?

1 writable?

dbit end

;db.phase1

;db.phase2

;phase1 = track*head*4/8

;phase2 = track*head*sectors*2/8

STRUCT END

Folder Binding

This is the first, or main, folder in the file drawer. It is the top level. Though it is actually the same as a normal folder structure, consider it as containing all the drawers of the drawer and what ever files are laying on top of it, if that helps you.

OBJECT.Class

Defines the device object to be used. Is a pointer to data at the end of the structure.

OBJECT.Instance

The instance of the device object to be used. A pointer to the name at the end of the structure.

General transfer type

How is data transfered to and from this device? memory sequential block network Cache

Returns the size of the devices cache, if any in, bytes. My Maxtor 524MB hard drive, for instance, would return 64kb.

AccessTime

Returns the sequential (track to track) and end-to-end (ie, first track to last track on a EIDE) access times for the device.

TransferRate

Returns the maximum, and averaged data transfer rates of the device. The maximum value is either obtained by direct query of the device, from the specs encoded in the driver, or through an approved test algorythm built into the function. The function should not take more than 5 seconds per iteration however the values are obtained, just to be polite.

The averaged data transfer rate is actually computed continually in real-time. Logs of the total amount of data transfer for each device are kept in it's root directory, as well as the accumulated wait time for each request from start to end. To get the average data transfer rate all that must be done is for the function to... well, take the average.

This is reset only during a reformat. Example returns for the maximum transfer rate are, say, a 14.4 modem has 1.6kb and a quad-speed CD 600kb.

Files

Returns the total number of all files in the drawer.

FileSpace

Returns the total amount of space on the device.

FreeSpace

Returns the amount of space all the files in the drawer take up.

Native_fs?

Is the drawer native fs?

Exist?

Does the device exist? Should always be 1.

Non-local?

Is the device not local? (across a modem, ISDN or IPX connection)

Boot?

Can you boot from this device?

Root?

Does this device have a root (supervisor area)?

See_filespace?

Can we see the devices filespace heirarchy?

WriteOverload

ReadOverload

Writable?

Can you write data to this medium? Not the same as asking if it is write protected.

Write_protected?

Is the current medium protected from changes to the data?

Removable?

Can the device be removed?

Removed?

Is the device currently empty of media?

Change_line?

Will the device tell you if it's medium has changed (ie, the floppy removed)?

Changed?

Has someone/something removed the medium since last time we checked.

Mirror?

Is the data written to the device mirrored elsewhere to provide for data integrity?

Error_state?

Are we detecting some kind of general error state from the device?

__FS.DRAWER_Information

__FS.DRAWER_SlackSpace

Computes the total amount of space on the device this is not being used but, due to speed optimization techniques, etc can not be used either.

__FS.DRAWER_Purge quality

Zeros out everything not in use in file-space of the current sub-root. This also means that any deleted files in the sub-root will be permanently lost. If the quality parameter is 0 (fast) then this simply writes 0 (NULL) to all the areas once. If it is 1 (secure) then it performs the much slower military-grade wipe.

CONTIGUOUS FILES AND DEFRAGMENTATION

At almost any time you desire, you can of course call up the non-instanced __ . This object class will defragment, compression, verify defects, and many other housekeeping operations to keep your filespace operating at efficiency.

Some of these operations however, will, unless you change the default policies, occur in the background as light threads. Most notable of these is the one that, if nothing else important is happening, go about defragmenting all files marked for contiguous high-speed streaming.

__DEFRAGMENT. refID

__DEFRAGMENT.Start

Initiates a collapse of all empty file-spaces of the current drawer. Returns NULL if fails, otherwise returns....

__DEFRAGMENT.Stop

__DEFRAGMENT.Status

FILESPACE ACQUISITION

There is, in every drawer as part of the drawer structure itself, what is known as the Rapid Filespace Acquisition Structure. This structure varies from device type to device type. There is currently defined the same structure on the IDE, EIDE ATAPI and FDC Floppy drives loosely called the CTS2P (Cylinder/track/sector/2-phase).

The filespace acquisition structures, no matter what device they are for, all are used to rapidly find space on a device when you wish to create a new file or change the size of a current one.

CYLINDER/TRACK PHASE

The first phase contains sets of nybbles, one for each track on the device. They are ordered by cylinder grouping. That is, if you have a drive that has 15 heads then you have 15 tracks per cylinder, and the first 15 tracks in the first phase are logically order top to bottom.

This nybble structure holds four bit-sized variables: AVAILABLE, FULL, UNUSED and DEFECTS. The boolean variable AVAILABLE indicates whether the track is available to GRAIL, or is thus otherwise in use by some other operating system or other purpose. FULL gives immediate response indicating whether the track is completely full already or not. UNUSED states that the track is completely unused is might make a good candidate for long contiguous streamed files. DEFECTS indicates that there is a problem with some sectors in the track, and thus influences the Defect Aversion strategy.

PHASE 1 Track/Cylinder Nybble Illustration
 _____________________________________________________
| AVAILABLE   | FULL        | UNUSED     | DEFECTS    |
|_____________|_____________|____________|____________|
The First Phase structure is small and used to rapidly scan the entire device filespace for a "general" area that may be suitable for the kind of file we wish to create.

For an IBM PC clone 1.4mb FDC Floppy Disc the first phase is 80 bytes in length.

SECTOR PHASE

The second phase gets down to specifics and maps the drive on a sector by sector basis. Each sector has a boolean pair of flags. USED simply indicates whether the sector is used or not. DEFECT indicates the sector is defective. Note that if DEFECT is set, then the USED flag indicates SOFT at 0 and HARD at 1. That is 01b is SOFT DEFECT and 11b is HARD DEFECT.

PHASE 2 Sector Pair Illustration ____________________ | USED | DEFECT | |_________|__________| For the 1.4mb disc, the second phase is 720 bytes in length.

DEFECT MAP

The defect map is incorporated directly into the Acquisition Structure.

DEFECT AVERSION

When trying to acquire filespace, all cylinders/tracks with DEFECTS will be avoided unless there is insufficient filespace to do otherwise. This takes place so as to avoid neighboring sectors in the same tracks which may also have some as yet undiscovered problems.

1.4mb FDC FLOPPY

Cylinders 80 Heads 2 Sectors per Track 18 Bytes per Track 9216 Bytes per Sector 512 Sectors 2880 Buffer ECC bytes GRAIL Phase 1 80 bytes GRAIL Phase 2 720 bytes Click here for Picture

162mb QUANTUM ELS170A

Cylinders 1011 Heads 15 Sectors per Track 22 Bytes per Track 11,264 Bytes per Sector 512 Sectors 333,630 Buffer 32kb ECC bytes 4 GRAIL Phase 1 7,582.5 bytes GRAIL Phase 2 83,487 bytes Click here for Picture

GENERATING THE ACQUISITION STRUCTURE

This structure is generated for quickly finding filespace, and consequentially, for avoiding defective areas. The area that a file occupies is contained in it's filemap, and not here. Every time a file is create or deleted, the acquisition structure is modified properly. Changes may also be made when routines are executed to verify that a device is defect free (and fails in someway).

________________________________________________________________________________

VIRTUAL DRAWER

_______________________________________________________________________________

When through a non-local filesystem interface you move through filespace, tokens are created on your systems representing the non-local systems observed in filespace.

Say for instance you visit ftp.cdrom.com (Walnut Creek Software) looking for new and exciting programs to download. Grail will create non-local/ if it has not done so already, then it will created non-local/ftp.cdrom.com/. Typically, since you have come in at the top level it will then create a folder for every subdirectory at their site and a token for every file, such as:

/non-local/ftp.cdrom.com/ ;folder bin/ ;folder pub/ ;folder readme.txt ;token While the concept of recreating non-local filesystems on your on system may sound a bit distressing at first, don't worry about it too much. All recreations occur in the virtual drawer non-local and all true files have only a token of their existence stored unless your software transfers them. This applies no matter what the source or the means of connection. When you are connected to computer systems that may not present a decernable filesystem (such as most current BBSes) then you must declare it's proper name to be used and all files are grouped into a single common folder. Take for instance, The Other World BBS, which ran under Major BBS software. The folder /non-local/The Other World BBS/ would be created and used.

Ideally however, the best BBS software would take advantage of this and use the STMP, FTP and HTTP protocols for their users, allowing easy file transfers.

Asides from being flagged as virtual, the virtual drawer is identical to virtual drawer.

________________________________________________________________________________

F O L D E R

_______________________________________________________________________________

The DATA BRANCH of the file called a folder contains a small header and then n binding structures. The header structure contains a count of the bindings in the folder (entries.total), and a count of the number of those that are actually in use (entries.current). There is also a variable (entries.highest) that shows the highest number of entries that have ever been in the folder at one time, and a variable (entries.created) showing the number of files that have been created in the folder. Unless you use a __SORTFOLDER or the binding decays by natural processes, deleted file bindings will remain for an undetermined peroid of time. The structure also contains a full binding that links back to the folders parent folder.

CLASS STRUCT FSS_Folder

ascii <FOLD>

d.8 filespace_bitwidth

STRUCT entries

fsdptr created

fsdptr highest

fsdptr total

fsdptr current

FF_binding up

STRUCT END

STRUCT END

;n bindings here...

__FS.MakeFolder ptr_folder_name

This creates the specified folder, returning error status if failure. A NULL means all works. A 1 means folder already exists, a 2 means the operating system is restricted from allowing you to do so. Returns the refID if successful.

__FS.RemoveFolder refIDlist

This removes the specified folder only if it is empty.

__FS.ChangeFolder refIDlist

All logical drives and directories in the grail fs are referenced by unique 32-bit refIDs. All requests to change folders are facilitated by a sequence of refIDs when you want fast response. If you do not know the refID sequence, you must use __FS.LookupFolderNames. The refID sequence is NULL terminated. Returns NULL on a failure, and the depth it obtained otherwise. Grail keeps two refIDpaths for each task. The primary (or source) path and the target path. Use __FS.tpath to change target path.

__FS.TargetFolder refIDlist

policy no/target.

__FS.ExchangePaths

Exchanges the current path with the target path.

__FS.UpFolder

Gets the up binding from the current folder and changes to that folder.

__FS.DownFolder refID

Goes down into a folder in the current folder.

__FS.FolderFiles type

Returns number of files in current folder. Type is created, highest, total and current.

__FS.FolderBindingsLength

Returns the size of all the bindings in the current folder in bytes.

__FS.GetFolderBindings ptr_folderbindings

Copies all the bindings in the current folder to the destination in memory. Returns the filespace bitwidth if sucessful, or NULL if not.

__FS.FolderrefIDsLength

Returns the size of all the refIDs used to reference the current folder, in bytes.

__FS.GetFolderrefIDs ptr_folderrefids

Copies all the refIDs referencing the current folder to the destination in memory.

__FS.LookupFile ptr_filename

Parses the current folder looking for the specified filename. If it is found then the function returns its refIDstring, else a NULL is returned. It also computes the folder depth of the file/foldername and passes it back.

(refID, depth) = _FS_refIDLookup()

__FS.LookupPath ptr_foldername

If you give this function the real name of a file path, it will create a NULL terminated dword list of all the refIDs required to move the position (a refIDlist). The refIDlist ..... Returns the depth of a file. ROOT is considered deep 1. Also useful in determining how much memory to allocate for a __FS.refIDpath call.

WHOLE FOLDERS

Need to move about entire folders and subfolders?

FOLDER.Move subfolders, overwrite, purge

Moves a folder, all its files and subfolders and merges them with the target. If subfolders flagged then copies subfolders as well. If overwrite flagged, then files with same filename over overwritten. If purge flagged, then files from the target folder are erased first.

FOLDER.Copy subfolders, overwrite, purge

Copies a folder from the current to the target folder. If subfolders flagged then copies subfolders as well. If overwrite flagged, then files with same filename over overwritten. If purge flagged, then files from the target folder are erased first.

FOLDER.Delete

Similar to __FS.RemoveFolder, this is more pervasive and dangerous, if the __FS.Policy settings allow it.

SORTING FOLDERS

This object class simply reads in a folder and sorts it by the most efficient algorithms possible, given the sort parameters. The target of the sort can be either an element of the binding itself, or a binary/string element of the associative branch. Sorting on the binding of course is faster since all the information is already in memory. The latter requires additional accesses to each files associative branch to extract the string that is to be sorted on.

SORTFOLDER.Binding element, direction

This function sorts on only elements from the binding. The elements are specified by number, the number being equivalent to the order of presentation of the element is the binding structure. Direction is either from lowest to highest (0) or highest to lowest (1).

SORTFOLDER.Associative ptr_name, direction

This function looks up an elements string from each files associative branch, storing them in memory (or the boolean truth of their existence) and then binary sorts on these strings. Direction can be from lowest to highest (1), highest to lowest (2) or a simple sort on their boolean existence.

________________________________________________________________________________

LINK

_______________________________________________________________________________

A link is a very simple thing. It's data branch contains two items: a full refIDlist URL and the unicode name of the URL. A link very simply points you to some other place in the filespace hierarchy. The command interface uses them to create an efficient personnel menu. Other applications use them for other reasons which anyone who has every used UNIX could explain to you. More later.

STRUCT FF_Link

fsptr refIDlist

fsptr URL

STRUCT END

; refIDlist goes here

; URL text goes here.

__FS.MakeLink ptr_URL

Creates a link in the current directory. You specify a pointer to the name of a URL, it is looked up and it's refIDlist created. The refIDlist and name are placed into the data branch. This function returns the refID of the new link, unless it fails then it returns NULL.

__FS.RemoveLink refID

Removes a link. Operates just like __FS.DeleteFile otherwise.

__FS.ValidateLink refID, trespass

If the target of the link exists locally, then the targets refId is returned. Else NULL is returned. If the target is non-local, then the trespass authority flag must set for the non-local filesystem functions to attempt to verify the link.

________________________________________________________________________________

A R C H I V E F O L D E R

_______________________________________________________________________________

An archive is almost exactly the same thing as a folder, except for a few minor deviations: You can not execute any objects within them, and most of their files can not be altered beyond simple creations, migrations and deletions. Also, every single file therein is compressed and possibly encrypted. This is in addition to any other compression and/or encryption.

An archiving operation effects the current folder and all folders and files therein. The functions start at the deepest sub-folders, if any, and work their way up to the current one, arching each file and folder as encountered.

Grail inherently supports archives through the FS hyper device object. While you can wander through the highly-compressed archives just like any other folder, you can not use them. Under the Natural Landscape Metaphor they look like they are encased in ice.

The archive object functions essentially take care of themselves. They will proceed until done, posting it's current status. Because of the time such a function requires however, you'd usually create a separate running active instance (a thread) and monitor it, providing semaphore and messaging information back to the user.

This obect class is bound.

__ARCHIVE_Archive

Archives the current directory and all folders and files contained.

__ARCHIVE_Unarchive

Unarchives all folders and files starting at the current folders down through the heirarchy.

________________________________________________________________________________

OBJECT FILE

_______________________________________________________________________________

This file type is explained in the core document.

________________________________________________________________________________

DATA FILE

_______________________________________________________________________________

[ed: revise!]

Grail has a general data type of file of course, but also has special recognition (optional) for binary documents, ASCII text document and UNICODE text documents.

TEXT ASCII/UNICODE

Normally, the subtype is not ignored.

As far as Grail is officially concerned, Plaintext has no binary control codes, excepting 13 to denote new lines (ie UNIX), 26 to end the page, 8 to tab, and 0 (NULL) to terminate the entire file. Grail has subtypes accepting either one byte ASCII (0), or two byte UNICODE (1). Technically GrayText, RTF, and HTML could also be considered plaintext, and probably eventually will be, in that order.

DATA FILE OBJECT-ORIENTATION

You can actually load a data file which the same functions that you would use to load an object assembled by GA. A data file can hold in its associatives a list of function names for the data file and the object/instance/function that this maps onto.

To clarify this, say we take our perennial example of Id Software's DOOM2.WAD. We could define it to have an open functions which maps to the object file DOOM][:/Open_Wad. By trying open DOOM2.WAD (clicking on it) will automatically startup the DOOM ][. When we are finished, we simple call the data file's Close function.

open

close

edit

save

load

abort

delete

display

print

_____________________________________________________________________________

PACKAGING:

MOVING FILES ACROSS NONLOCAL DOMAINS

_____________________________________________________________________________

When you move a Grail file, you move three parts, the Binding, The Associative Branch and the Data Branch. And in that order. Moving files locally from folder to folder is no problem. Moving them across a non-local domain such as a modem or IPX network is slightly different, but still no problem if two Grail systems are communicating with each other since the binding/associative/data trio is sent as one bound data stream. When transmitting files for storage on non Grail systems however there are definite problems. If they are not set up to understand GFS, you must package them. When you package a file you create a single file that is composed of a binding, an associative branch, and data branch. Used for transport across other systems or for packing files.

A package, thus, is one single large file containing either one or many other files. The header structure is

CLASS STRUCT

ascii <PACK>

d.8 filespace_bitwidth

fsdptr binding_length

fsdptr entries ;0=file, other is folders

fsdptr folders

STRUCT END

followed by several structs of

CLASS STRUCT

fsdptr folder_name

fsdptr associative

fsdptr data

STRUCT END

After the struct then follows the folder name, if any, then the associative branch and then the data branch. The folder name points to a title:subtitle string which is the name of the folder the following file comes from. If it is NULL, then we use the last declared folder name. If there is no folder name declared in the entire file, then we assume the current folder.

__FS.Package refID

Copies binding, data and associative branch into a new data area and creates a file of package type.

__FS.Unpackage refID

When you receive a Grail archive from a machine that doesn't understand such things it will be held in the package format. Which means after it is transferred to you, you will execute the __FS.Unpackage function which will unpackage the file into an archive and delete the packaged file in the process.

FOLDER.Package

Packs an entire folder and its subfolders.

FOLDER.Unpackage

Unpacks an entire folder and its subfolders.

________________________________________________________________________________

S T R E A M F I L E H A N D L I N G

_______________________________________________________________________________

Handles are all pointers to a buffer in memory (header) created specifically for THAT file. Each file opened allocates memory such as:

OPENING SAME FILE MULTIPLE TIMES

You can open a file multiple times without question most of the time. You can also lock the file while you make serious changes. However you do it, you are guarented that each read/write struct will be moved whole. No locking is required.

Note that ....

ADAPTIVE CACHING

STREAM HANDLE STRUCTURE

STRUCT HANDLE_STRUCT

binding_struct binding

fsptr position

fsptr position_write

fsptr buffer_length

dbit.32 status

1 write_buffer

1 read_buffer

1 write_status

1 read_status

1 locked

;keep in mem?

1 name

1 data_maplist

dbit end

STRUCT END

; nbytes name

; nbyte buffer

; nbytes data maplist

; nbytes assc maplist

__FS.Open refID, mode, lock, caching

Allocates memory for a filestream header. The function returns a pointer to the file stream structure. A NULL indicates failure. If lock is flagged, then the file will be locked on open. Modes are readonly (0), writeonly (1), readandwrite (2). If caching is 0, then no caching is used. If 1, then adaptive caching scheme is used, which may use up a noticable amount of memory.

__FS.Close handle

By giving this function the handle of a file, you can close the file. The buffer will be flushed and the stream structure deallocated. It returns NULL if it fails, 1 if close, or 2 if it had to flush data when closing.

__FS.ReadStruct handle, fsdptr_length, ptr_destination

Reads in fsdptr length of bytes of data from file handle to the pointer address at ptr_destination. Returns NULL if file not open or open for write only. Also returns (in EBX) the status induced by the read:

0 No problems

1 Not opened/valid

2 Locked

3 BOF

4 EOF

__FS.WriteStruct handle, fsdptr_length, ptr_destination

Writes out fsdptr length of bytes of data from file handle to the pointer address at ptr_destination. Returns NULL if file not open or open for write only. Also returns (in EBX) the status induced by the read:

0 Write to extend

1 Not opened/valid

2 Locked

3 Desync Write to beginning

4 Overwrite

__FS.ReadASCII handle

Returns one binary ascii character back in a byte. Also returns (in EBX) the status induced by the read:

0 No problems

1 Not opened/valid

2 Locked

3 BOF

4 EOF

__FS.WriteASCII handle, char

Puts the ASCII character into the stream of the specified handle. Also returns (in EBX) the status induced by the read:

0 Write to extend

1 Not opened/valid

2 Locked

3 Desync Write to beginning

4 Overwrite

__FS.ReadUnicode handle

Returns one binary unicode word back. Also returns (in EBX) the status induced by the read:

0 No problems

1 Not opened/valid

2 Locked

3 BOF

4 EOF

__FS.WriteUnicode handle, unicode

Places the word-sized unicode character into the stream. Also returns (in EBX) the status induced by the read:

0 Write to extend

1 Not opened/valid

2 Locked

3 Desync Write to beginning

4 Overwrite

__FS.ReadPosition handle

Returns the current position in the file.

__FS.ChangePosition handle, position, method

Changes the position in the file absolutely (0) or relatively (1).

__FS.Position handle

Returns the file position.

__FS.PositionOk? handle

-1 beginning of file detected (BOF)

0 ok

1 end of file detected (EOF)

__FS.Direction handle, direction

Normally a stream instruction will move your position forward in the file. You can set to move backward though as well. Note that for structs, it read the struct in correctly, and only changes position afterward. Forward is 0, backwards is 1.

__FS.Direction? handle

Returns 0 for forward, and 1 for backwards.

__FS.SearchNULL handle, ptr_string, location

Same as __FS.Search but it computes the length by doing a search for NULL first.

__FS.Search handle, ptr_string, location, length

Searches forward in a file (data branch) for the supplied data.

__FS.Cut handle, location, length

Collapses the file by the specified part.

__FS.Insert handle, position, length, ptr_data

Inserts new data into the specificed position of the file, using the data pointed to in memory.

__FS.InsertNULL handle, position, ptr_data

Computes the length of a piece of text data, then inserts it into the specificed position of the file, using the data pointed to in memory.

__FS.Crop handle, location, length

Removes everything from the file but the part bounded here.

__FS.IsLock? handle

Return boolean truth of whether file is locked or not.

__FS.Lock handle

Locks the files so no other processes from the same processor or another one in the symmetric system can use it.

__FS.Unlock handle

Unlocks the file for use.

______________________________________________________________

OPERATIONS ON WHOLE FILES

______________________________________________________________

__FS.Create mode, contiguous, reserved

Creates a file, and returns it's refID. The file that is created is simple and unadorned. No data branch at all in fact. Only the binding, and it's associative file. The modes are read, write, and readwrite. If the contiguous flag is set, then the OS wll try to keep the file contiguous. Reserved indicates an amount of fsdptr contiguous filespace that the os should try to reserve for the file.

__FS.Copy refID

Makes a copy of the specified file and places it in the target folder.

__FS.Move refID

Moves refID file from the current source directory to the current target directory.

__FS.Replace refID, refID

Replaces a file with another one.

__FS.Replicate refID, ptr_filename

Makes an exact replicant of a file with a new name.

__FS.Delete refID

Removes the link to the binding from the root, and marks the files binding as deleted. The bind is changed to "bind" (in lower case).

__FS.DeleteSecure refID

Same as __FS.Delete, but forces a secure delete -- zeros all the entire space of the file and then zeros out the binding.

__FS.Append refID, refID

Copies the data branch of refID and tags it onto the end of refID target file.

__FS.Purge refID

Deletes all but the newest version of a file. Also removes tokens.

__FS.PurgeSecure refID

Deletes all but the newest version of a file, but securely -- zeroing out file space.

__FS.Backup refID

Creates a newer version of a file... an exact copy.

__FS.Compress refID

Compresses the file, then sets the compress bit on. From now on, every time this file is accessed or loaded, it must first be uncompressed. Compression is by the standard huffman variant. Uses __COMPRESS.

__FS.Uncompress refID

Uncompresses the file, then turns off the compress bit. Uses __DECOMPRESS.

______________________________________________________________

MEMORY / FILE EXCHANGES

______________________________________________________________

These functions allow you to simply open a file into memory, modify it, and then close it back out to the file. Simple enough, eh? Pretty much. When you open a file thusly, it allocates an area in memory to hold the contents of the file (it's data branch) and another area to hold a small amount of information on the file itself (the file's name, URL, etc).

When these function are used on it file, it;s policy is automagically changed to promote high-speed streaming of data over other considerations (ie, contiguous files) but also that buffering is not required.

[min: Those of you who have been following Grail design for a while may notice that Data Godets have disappeared. :( Don't worry. The are safe in GODET.DOC, but because of complications, the concept may not make it into Grail for a while. If they do they will be subsumed by this function set. Godets, for those of you who don't remember, allocated unused address lines and some real physical memory to effectively load files up to 4gb into memory as thier own virtual swapfile system. Wanna mount an entire DVD into memory? Go for it.] __FS.OpenData refID

This open a file into memory. Returns NULL if fails. Otherwise return backbone handle.

__FS.CloseData handle, flush

If flush is 0, then this simply __MMU.Deallocates the data and file handle areas from memory. Otherwise, it first writes this memory back out to the file. If the memory area has been resized, then so too will be the file.

__FS.WriteData refID, handle

After you have created a file (for example, with __FS.Create) you can write out an area of allocated memory to a file.

________________________________________________________________________________

D A T A G O D E T

________________________________________________________________________________

A godet is a very large (read-mostly) file that is opened and mapped into the 4GB (2^32 byte) range of memory through paging. You can specify the amount of real memory to allocate for each godet. The point of this is to be able to access huge data files AS IF they were completely in memory, without creating wasteful swapfile space.

Each Godet file opened performs a non-vmmu memory allocation for space, and marks all it's pages as not present. The size of the page table/directory is changed as necessary. ID's WAD files would be good godet candidate. If you had assigned 256kb per godet, then the 14mb DOOM2.WAD would take up only 256kb of memory even though it 'owned' 14mb of the 4gb address space in your system. There is an overhead of about 14kb for additional page tables as well.

Why not just cache it, you say? Well... we sort of are, selectively. But this allows us to drop the annoying fopen/fseek jargon and access our data more naturally. It's a compromise hybrid between caching and virtual memory.

To clear things up, let us say that the average swap file is a public or common structure. A Godet is a specific swapfile which uses a named file that typically is preexisting. The file continues to exist afterward as well. For example look at this sample memory map that has three files open as godets:

VMMU/GODET MEMORY MAP |-----------------------| | | | Unused Address Space | | | |.......................| ---- | GODET #3 | |.......................| | GODET #2 | |.......................| Virtual Memory | GODET #1 | |.......................| | | |Virtual Memory (Common)| | | |.......................| ---- | | | Real Memory | Real Memory | | |-----------------------| A godet allocates three things: An area to hold information on the file where the data is held, ........

__FS.OpenDataGodet ptr_filename, address_size, physical_size, type, lock

This function allocates a block of address space above your linear memory and a certain amount of real DRAM memory. The pages of real memory that it allocates are marked as belonging to a godet through bit 9 of the PTE.

Intel Page Table Entry (PTE) Illustration
	31                                       12 11               0
--------------------------------------------------------------------
|                                          | | | |   | | |P|P|U|R| |
| Page frame address 31..12 of linear mem  |Avail|0 0|D|A|C|W|/|/|P|
|                                          | | | |   | | |D|T|S|W| |
--------------------------------------------------------------------
Bit 9 in Grail is used to mark a page as not free for allocation by common VMMU functions.

When a Godet is allocated, it also opens a file handle to it which is used to figure where to transfer data. A Godet uses two MMU entries. The second one follows directly after and has a MMU.flag.link of 1. This structure supplies the pointer to the file system file handle. Both MMU entries are chained together thusly through this structure:

STRUCT

ptr handle ;handle is the 32bit offset to memory

ptr FS ; <<-- NOTE

ptr object ;ptr to object handle that created it

dbit.16 flag

1 deny ;denied hardware or core area

1 dma ;normal/DMAable

1 secure ;unsecure/secure (personnel/supervisor)

dbit end

dbit.16 style

4 module

4 align

dbit end

STRUCT END

See description above. Returns a MMU style handle in ESI.

Type...

0 normal

1 GODET

Above the __FS file system this simple allocates memory the same size as a file and then copies the data from the file to memory. Returns the MMU handle or NULL if there is a problem.

As an example, this script virtually loads the doom2 wad into memory on a 4mb computer:

wad = __FS.OpenDataGodet "Doom2.wad", 14680064, 524288, godet __FS.CloseDataGodet wad __FS.CloseDataGodet handle

Closes the godet.

_____________________________________________________________________________

D A T A B R A N C H

_____________________________________________________________________________

The raw data of a file or application, etc. The contents of the file are not the concern of the operating system, unless it's a control, device driver, folder, or link file, which are system constructs. Those are described elsewhere.

_____________________________________________________________________________

A S S O C I A T I V E B R A N C H

_____________________________________________________________________________

An associative branch is in some sense an extension of the binding information. Within it is held the vital Associative and Data Branch filemaps, system information on the file, application and personnel settings. The binding is some times called the header. The associative and data branch together are called the body.

File Illustration

Binding _|________________________ | | Associative Branch Data Branch | |-Associative Filemap |-Data Filemap + |-System |-Application |-Object '-User# An item can multiple instances of it if it makes use of this. If this is 0, then numbering is not used. If it is 4, then a byte prefaces the stream. If a 6 then a dword.

STRUCT FF_Associative

ascii <ASSC>

d.8 fs_bitwidth ;2^(n-1)

fsptr FSS_Binding binding ;back-link to binding

fsptr assc_ptr

fsdptr assc_length

fsptr data_ptr

fsdptr data_length

fsptr other_ptr

STRUCT END

STRUCT count

fsdptr system

fsdptr application

fsdptr object

fsdptr user#

fsdptr total

STRUCT END

__FS.AssociativeAdd type, no, refID, ptr_name, ptr_value, length

Add or changes a specifically named group item, depending whether it already existed.

__FS.AssociativeAdd_NULLStream type, no, refID, ptr_name, ptr_value

This is the same as __FS.AssociativeAdd excepting that it looks for a NULL to terminate the stream and computes the length for you. Used when moving around text. Use the other for data. Note that your language policy setting will influence whether it looks for an 8-bit or 16-bit NULL. Actually just computes the length and then calls __FS.AssociativeAdd.

__FS.AssociativeDelete type, no, refID, ptr_name

Deletes the specified item. If no is 0, then all such items are deleted, otherwise only the one matching the numbering.

__FS.AssociativeVerify type, no, refID, ptr_name

Asks if the specified item exists, and how long it is. Returns exist and length such as:

(exist, length) = __FS.AssociativeVerify Personnel, All, "Bookmark"

__FS.AssociativeGet type, no, refID, ptr_name, ptr_dst

If the item exists, this copies it to ptr_dst.

__FS.AssociativeCountNo type, refID

__FS.AssociativeGetEntry type, no, refID

__FS.AssociativePurge type, no, refID

ASSOCIATIVE AND DATA BRANCH FILEMAPS

Many of you may be used to, or know of the FAT Filesystem used by MS-DOS. Grail's filesystem is nothing like that. Each individual file is responsible for it's own mapping onto a drive. Since files can be flagged to be contiguous there is less thrashing about of files, this isn't as much of a problem as you might think.

The filemap is a totally different structure depending on your type of drive. It is an architecture dependant area used directly by the low-level filesystem device objects. It operates in sectors on IDE and floppy drives, but not so with modems.

What happens when your drive does not have enough contiguous space to create a file? You get an error of course. Two things can happen. You can defragment the drive, or you can complain to the user there is too much clutter on it. You can defrag directly, or set up the defaults to automatically attempt a defrag if filespace gets low.

The root contains a list of pointers to the filemap of every single file on the system. That is, for instance, one of my partitions has 4869 files on it. So the root has 19,476 bytes of file pointer info in it. This list is used whenever a file is created or is modified in size so as files don't overlap one another.

The Grail filesystem is designed to quickly read files, though it is slightly slower in creating them.

For an IDE drive the filemap is a dword denoting now many sectors are in the file, the size of a sector, Grail IDE sectors being fixed at 512 bytes, followed by the starting and ending sector numbers.

SYSTEM

Classification

Two ASCIIZ13 lines. First has general classification. Second has specific format used. You should also use the type and subtypes, to give your a four data defination of a file. For example:

Image/JPEG

Image/PNG

Sound/VOC

Animation/FLI

object/script

Data Compression

Is the data branch compressed? Compression effects the entire branch. This is the name of the algorythm to use.

Asscociative Compression

Is the associative branch compressed? Note that unlike the data branch, compression in the associative branch only occurs AFTER the assc compression tags (otherwise you wouldn't know what compression was being used. :)

Encryption

Decryption

Object

Name

One ASCIIZ line. The name given to the file. Can be anything up to 4GB.

Error_log

asciiz13.

History_log

asciiz13.

Registration_key

Application

For data. The name of the application that has created or last edited this file.

Age

APPLICATION

Application

Name of application this object belongs to.

Comment

ASCIIZ13 comment. Usually a description of the file.

Author

ASCIIZ13 about or naming the author.

Legal

ASCIIZ13 legal notice.

Own

A list of the files that the app brought to your system. asciiz13.

Remove

A list of the files that should be deleted when the app is removed from your system. asciiz13. Listed with folders, etc.

Original_Conception

TimeDate of the conception or original start of the project, document, etc.

Issue_Conception

The timedate for this particular issue in a series.

Title= The Warlock Cipher

SubTitle=

Author= Lewis Sellers

Platform= GRAIL/IBM

House/Company= TMG/Grail

Date= 1 July 1995

Technical Support Line= 1(800)999-9998

Fax= phone://1(800)999-9999

Business Hours= 7:00pm to 7:10pm EST

EmailInfo= info@grailos.org

EmailHelp= help@grailos.org

MailingList_Subscribe= infoserver@grailos.org subscribe grailos

MailingList_UnSubscribe= infoserver@grailos.org unsubscribe grailos

WWW= http://www.grailos.org/

FTP= ftp://ftp.grailos.org/pub/

NewsGroup= alt.os.grail.d

NewsGroup_d= alt.os.grail.d

NewsGroup_Binaries= alt.os.grail.binaries

RAM=8mb,16mb

HD=37mb,450mb

CPU=486,Pentium

FPU=No,Yes

Drystones=

OBJECT

path, object, function

open

edit

close

USER# GROUPS

STRUCT

STRUCT Name

fsdptr length

fsptr start

STRUCT END

fsdptr length

fsptr start

d.8 type

d.8 numbering

STRUCT END

Now this is a little different than the other groups. The normal name/data structure is prefixed by a NULL-terminated user name identifying each as uniquely belonging to a certain user. Grail ignores all but the one relevant to the current user. While in supervisor mode you can however effect all the others.

Bookmark (saved game)

this data is what some might called a "saved game". the data is defined by the objects. This item uses the numbering feature, so that you can have multiple bookmarks.

Session (session saved state)

the saved state of the system. fast resumes. A sort of master bookmark.

Guise Position

The actual position of the guise. Whether the metaphor uses everything or not is up to it.

STRUCT guise_position

d.32 x

d.32 y

d.32 z

d.32 xr

d.32 yr

d.32 zr

d.32 ?

d.32 ?

STRUCT END

Guise Iconic

A two-dimensional icon. Grail standards are for images to use an RGB colorwheel mapped to whatever bitdepth is currently used. This allows for fast translation between depths. The header is:

STRUCT guise_icon_header

d.16 width

d.16 height

d.8 bitdepth ;8,16,24

d.8 ?

d.16 ?

STRUCT END

The data then follows logically, starting at x0,y0, progressing positively through the x, and then line by line to the bottom right of the image.

Guise Audial

STRUCT guise_audial_header

d.8 bits ;4,8,16,18,20,24

d.8 channels ;1,2

d.32 frequency

d.8 range

d.8 ?

STRUCT END

The data follows. The channels are lain out next to one another. It is fine to use audial and iconic guises together.

Guise Movie

A movie is a series of icons with same-size clips of audio interspacing them. Data always starts with icon, then audio section. then alternates. The header is:

STRUCT guise_movie_header

d.16 width

d.16 height

d.8 bitdepth

d.8 bits

d.8 channels

d.32 frequency

d.8 range

d.8 ?

STRUCT END

Please note that while MPEG1, MPEG2 and Quicktime are the favored true movie formats for use by Grail, this is the native format that is supported by all versions of Grail. You probably will want to use the other formentioned formats for commercial products.

Guise Interactive

This is actually the name of an object or program that manages the appearance of a guise as an active task. Some are specific to an application, some are generic and work on all programs. The metaphor, if it handles these, will start up the object and send the name of this object to it.

Preface

The Glass Metaphor places this image up on the screen as soon as the primary object of an application is started. You should put these images ONLY on the primary object in an application and no where else. The structure is the same as the Guise Iconic.

_____________________________________________________________________________

SELECTION

_____________________________________________________________________________

Selection

Select.Folder

Select.File

Select.Mask

?

*

Unselection

Unselect.Folder

Unselect.File

Unselect.Mask

Selection Action

struct

{

int total

int processed;

int ignored

int overwritten

int missing //_from_source

};

Selection.TotalLength memory_handle

Selection.TotalSize memory_handle

Returns the total amount of space occupied/required by all the selected files.

Selection.Delete memory_handle

Selection.Copy memory_handle, adversity_response, heirarchy, progression

Every file that is successfully copied, is "tagged". This allows you to more easily create a database of problem files using other selection functions.

Adversity_response,

If file already exists at destination

ignore

overwrite

overwrite with newer only

if source file does not exist when called for,

skip

abort

if can not write to destination (not enough space),

skip

abort

if source device off-line,

abort

wait device cycle

if destination device off-line,

abort

wait device cycle

if destination device saturated,

abort

wait

?

Heirarchy,

relative, starting at current destination folder

absolute, starting at root

Progression,

Continuous

Stop at each action

Stop at each failure

Selection.Move memory_handle, adversity_response, heirarchy, progression

Selection.Continue memory_handle, progression

Selection.Position memory_handle, where

Selection.CurrentEntry memory_handle

Returns the current entry

Selection.PurgeTagged memory_handle

Selection.CropTagged memory_handle

Selection.SplitByTag memory_handle

Selection.Untag memory_handle

This removes the action flag from all files in selection structure.

Selection.SortbyFolder memory_handle