> # 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
> - http://www.dwc.edu/grail/
> - http://www.usit.net/public/bcannon/grail/
> 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 | S C R I P T

> ### DESIGNER

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

> ### CRITIQUED BY

> - Akintunde Omitowoju tunde@housing.east-tenn-st.edu (a0.01)
> - Luc Stepniewski stepniew@isty-info.uvsq.fr (a.001)

> ### DRAFTS

> - ? v0
> - 1/24/96 revision 0.0
> - 2/6/96 revision 0.01
> - 2/16/96 revision 0.02 (redress)
> - 7/31/96 revision 0.03 (begin for www 0.12...)

> TOC

> # (a0.03)

> # Table of Contents

> Legal Notices | Who gets sued and why
> History | Changes and who made them
> Preface | About this document and the people that make it

> Overview | An Overview of the Script

> TOC

> # An Overview of the Script

> BY | Lewis A. Sellers lsellers@usit.net

> As you know by now Grail lives and dies on the concept of objects. Most the documents to this point have talked about precompiled object classes. But that is not all....

> Down in current or default User Resource File there is an area called SCRIPT_LANGUAGES. There you can define file types that should be treated as executables even though they are not. GrailScript, as well as the familiar Perl, are script languages. That is, they are plaintext documents that contain code that is not precompiled. If you were try to load a GrailScript document like an object, the __SCRIPT object would be loaded and the name of the document passed to it. It would then be converted to assembly language and the Grail Assembler would finish compiling it into an object direct to memory.

> This is not to say that a script language can not be interpreted (like BASIC) or other than plaintext (such as the byte-coded JAVA by Sun Microsystems), just that GrailScript is not.

> With GrailScript the file is compiled into a binary executable which is left in memory just like, as was said, any other object. This compilation is temporary. If the object is discarded, then so is the binary image of the script. Thus, they are not the fastest thing on the earth, but they should be completely cross-platform portable and work on any Grail system. People who might write scripts are librarians, site maintainers, museums, governments, etc. :) People who don't write applications in script are generally in the entertainment field.

> Further, the use of grail script is fairly ideal for those putting out CD-ROM's which are archival in nature (images, texts, etc) or that accompany movies with behind-the-scenes notes, images, sounds, etc. You can have write the presentation program in platform-neutral SCRIPT and have it work on anything that runs Grail.

> The script language is a relatively simple thing being somewhat akin to C and Perl. You can declare variables that are scoped, as well as create functions for objects and call the functions of other objects. All objects and functions are references by their native nomenclature.

> The function names creation, and destruction are special, and exist in all scripts. The main function exists only in object that are meant to run in and of themselves. The function creation is executed after an __OBJECT_Request and it's return value is passed back as the return. The __OBJECT_Discard executes the destruction function before preceding. The return value should ways be an integer. Creation and Destruction MUST exist or an __OBJECT_Request will abort.

> On a side note: Around the beginning of 1996 I became aware of Java by Sun Microsystems and JavaScript by Sun and Netscape. After examining the documentation on them it became clear that much more work should go into allowing a task or object to be nearly hermetically isolated from the rest of the system. Though they did not influence the design of Grail significantly (the Grail APIs were near final solidification by the time they came about) their existence was responsible for the addition of the hermetic object policies.

> Anyway, now you know why the Grail Assembler is included with all versions of Grail. After __SCRIPT (or __SCRIPT/PERL, etc) has converted code to assembly source, then GA creates a Grail compat binary in the current module format directly to memory.

> I suppose it's a little strange to have script language support built directly into a kernel... but Grail is a little unusual anyway. (And he falls asleep on his christmas tree. :)

> __SCRIPT Invocation

> The object class __SCRIPT belongs to Grail Script. When a script file is ran, it is naturally brought into existence to compile the script, but it also stays around after, placing itself into the objects auto-discard list. The reasoning behind this is that __SCRIPT brings with it several very useful and commonly used functions that will make your life easier. See SCRIPT PUBLIC FUNCTIONS later in this document.

> TOC

> # Keywords and Directives

> BY | Lewis A. Sellers lsellers@usit.net
> Grail Script Declarations, Keywords, and Operands

> As said, Grail Script is a slightly stripped-down C perl-ized language. If you're familiar with C and have read the rest of the kernel specs then learning GS should not pose a problem. Notice however that GS does allow for returning more than one parameter from a function. To call functions of other objects you must use the __OBJECT_Function function. To call functions within your current class you just directly call them.

> As said, you can return either one variable (which can be pointers), a group of variables, or return a filled structure (that is, fill out a structure with data). The symbol for structure returns is =.

> You can declare the following types of variables:

> byte,sbyte

> 8 bits

> word,sword

> 16 bits

> dword,dword

> 32 bits

> qword, sqword

> 64 bits

> ptr

> The pointer size depends on your implementation of Grail. Currently its 32-bits (dword) on the IBM PC platforms.

> int

> The default int is the most natural size for your platform. On the intels this is a 32-bit dword. There are also the modifiers fast and exact. A fast int on the intels is also 32-bit dword. The exact int is a 64-bit quad-word.

> fixed

> This performs balanced fixed point real operations. The default natural size is 16.16 or a 32-bit dword. The fast fixed is also 16.16. The exact fixed is 32.32.

> float

> These variables are real floating point. The default natural size is 80-bits. The fast float size is 80-bits. The exact float size is 80-bits.

> Bitsizeof

> Want to know what size the Grail Script is currently using? It has a built-in function called bitsizeof that can be used as:

> n = bitsizeof exact fixed

> that returns the total bits used in the variable type. N would be 64 in this case. There is also bitsizeofA and bitsizeofB that can be used to query fixed and floating variables for the size of their real and fractional components.

> assignments, =

> Same as in C, but be aware that Script fully supports passing full and complex structures. :) Passing back or assigning variables is as usual, but when structure are involved you must use a pointer to said structure.

> pointer, *

> When using a pointer, you can either use the C-ish * symbol or you can use the full word pointer.

> ******

> and, &&

> or, ||

> xor, ^^

> bitwise and, &

> bitwise or, |

> bitwise xor, ^

> bitwise complement, ~

> +=

> -=

> *=

> %=

> <<

> >>

> Auto-increment, ++

> Auto-decrement, --

> ******

> equals, ==

> not equals, !=

> less than, <

> greater than, >

> less than or equal, <=

> greater than or equal, >=

> not, !

> ********

> for (initializes, while, opers)

> Same as in C.

> if () then {} else { }

> Same as in C. If you only have one comparision, then parentheses are not required.

> while () { }

> Same as in C.

> until () { }

> Same as in C.

> do { } until/while { }

> Same as in C.

> object

> declares the name of the script. should be the same as the filename of the script.

> objects

> remarks, ;

> This is the remark symbol. Same as in normal intel assembly. Remarks the rest of the line.

> struct name {}

> Can also use structure.

> template name {}

> defines the structure that is to follow as merely a template that may have many instances. Use the name of the template from now on like the struct keyword.

> common /end

> These variables and structures are allocated and deallocated automatically for the object.

> function /end

> Declares a function body. Use end to end the function body. You can, BTW, put an end in a conditional block to terminate the process early. If the keyword function is preceeded by public then the function is added to the publics list (PDL). By default all functions are private, ie local to it's object class.

> alias

> Allows you to specify that when you make a function call that it should actually use another of it's sibling functions. For when two or more functions are identical for a given object. The alias should be given after the function line and include the true sibling to use. See examples.

> return

> Defines what, if anything, is returned when the function ends. By default, if you do not specify a return, then NOTHING is returned. Any variable, set of variables or structures can be returned.

> If you specify end without any args then you can return an immediate value (32-bits or dword on intel) as an arg to the end of a function.

> parameter (object parameter definitions list)

> Defines a list of parameter text aliases that can be used for an object function. It should be mentioned that Grail Script IS fully aware of the function parameter text lists that all object modules under Grail may possess. This is to say, instead of __VMODE_Use 0, you can say __VMODE_Use mono.

> TOC

> # Script Class Functions

> BY | Lewis A. Sellers lsellers@usit.net
> __SCRIPT_Creation

> Doesn't do much of anything.

> __SCRIPT_Process ptr_filename

> Takes a script file, converts it to assembly, calls the Grail Assembler and compiles it into memory.

> __SCRIPT_Destruction

> Doesn't do much of anything.

> TOC

> # EXAMPLES

> BY | Lewis A. Sellers lsellers@usit.net
> Script EXAMPLE 1 (fragment)

> ; sample of new metaphor structures....???

> dptr win1

> int r1, r2

> win1 = __METAPHOR_WindowOpen

> __METAPHOR_WindowSize win1, 100,480,0

> __METAPHOR_WindowOrientation win1, 0,0,0

> r1 = __METAPHOR_AddRegion win1, Title, 0,0,0, 99,19,0, NULL

> r2 = __METAPHOR_AddRegion win1, Text, 0,20,0,99,479,0, NULL

> __METAPHOR_WindowShow win1

> __METAPHOR_WindowPrint win1, r1, "COME AND WASH AWAY THE RAIN"

> __METAPHOR_WindowPrint win1, r2, "Hey there... this is a test.\n"

> __KEYBOARD_ReadKey

> __METAPHOR_WindowHide

> __METAPHOR_WindowClose win1

> Script EXAMPLE 2 (Full Program)

> ;-------------------------------------

> ;This little script opens a console window and prints out your computers memory.

> ;It does make use of someones helpful functions from an object called __SCRIPT. :)

> ;-------------------------------------

> function Creation()

> end

> function Destruction()

> end

> public function Main()

> ptr Wait

> ptr OpenWin, Print, CloseWin

> int total_memory, l1_cache, l2_cache, cmos_memory

> __OBJECT_Request QUICK_KEY

> Wait = __OBJECT_Function QUICK_KEY, Wait_For_Press

> __OBJECT_Request __SCRIPT

> OpenWin = __OBJECT_Function __SCRIPT, OpenWindow

> Print = __OBJECT_Function __SCRIPT, Print

> CloseWin = __OBJECT_Function __SCRIPT, CloseWindow

> (total_memory, l1_cache, l2_cache, cmos_memory) = __KERNEL_Memory()

> OpenWin()

> Print("Total Memory:",total_memory,"\n")

> Print("L1 Cache: ",l1_cache,"\n")

> Print("L2 Cache: ",l2_cache,"\n")

> Print("CMOS Memory: ",cmos_memory,'"\n")

> Wait()

> CloseWin()

> __OBJECT_Discard __SCRIPT

> __OBJECT_Discard QUICK_KEY

> end

> Script EXAMPLE 3 (Full Program)

> function Creation()

> end

> function Destruction()

> end

> public function Main()

> ptr Wait

> ptr OpenWin, Print, CloseWin

> ptr platform, processor, system

> ptr block,n

> Wait = __OBJECT_Function __SCRIPT, Wait_For_Press

> OpenWin = __OBJECT_Function __SCRIPT, TextWindow_Open

> Print = __OBJECT_Function __SCRIPT, TextWindow_Print

> CloseWin = __OBJECT_Function __SCRIPT, TextWindow_Close

> platform = __KERNEL_Platform_Name()

> processor = __KERNEL_Processor_Name()

> system = __KERNEL_System_Class()

> (total_used_memory, total_used_secure, total_swapped_out, total_used_DMA) = __MMU_UsedSpace()

> (largest_freespace, largest_DMA_freespace) = __MMU_Fragspaces()

> (smallest_freespace, smallest_DMA_freespace) = __MMU_Fragspaces()

> OpenWin()

> ;show us some stats....

> Print("Platform: ", platform,"\n")

> Print("Processor: ", processor, "\n")

> Print("System: ", system,"\n")

> Print("Total Used Memory:", total_used_memory, "\n")

> Print("Total Used SECURE Memory:",total_used_secure, "\n')

> Print("Total Used DMA Memory:", total_used_DMA, "\n")

> Print("Total VMMU Swapped-out Memory:",total_swapped, "\n")

> Print("Largest Freespace:", largest_freespace, "\n")

> Print("Largest DMA Freespace:", largest_DMA_freespace, "\n")

> Print("Smallest Freespace:", smallest_freespace, "\n")

> Print("Smallest DMA Freespace:", smallest_DMA_freespace, "\n")

> ;allocate almost a meg of memory, write to it, and then kill it...

> block = __MMU_Alloc 1000000, default, normal

> for(n=block,count=1000000;count>0;n++,count--)

> {

> *n=0 ;set to 0

> *n=1 ;then set to 1 for no reason...

> }

> __MMU_Free block

> Wait();

> CloseWin()

> end

> Script EXAMPLE 4 (Full Program)

> ;--------------------------

> ; This simple little script loads in a JPEG using the standard JPEG object,

> ; then blits the image to the graphics screen.

> ;--------------------------

> function Creation()

> end

> function Destruction()

> end

> public function Main()

> struct m

> {

> word zoom_x

> word zoom_y

> word aspect_x

> word aspect_y

> dword width

> dword height

> byte bitdepth

> }

> ptr dejpeg

> ptr logo

> struct jpeg_struct

> {

> word aspect_x

> word aspect_y

> dword width

> dword height

> byte bitdepth

> }

> struct bitBLT_form

> {

> word srcleft

> word srctop

> word srcright

> word srcbottom

> word srcpage/plane

> word dstleft

> word dsttop

> word dstpage/plane

> word x_type

> word y_type

> word bitdepth

> }

> m.zoom_x=1

> m.zoom_y=1

> m.aspect_x=4

> m.aspect_y=3

> m.width=640

> m.height=480

> m.bitdepth=8

> __VMODE_Request_Mode normal, higher_color, m

> __VMODE_Use mono

> if m.bitdepth<8

> end

> endif

> ;grab the jpeg image into memory...

> __OBJECT_Request JPEG

> infojpeg = __OBJECT_Function JPEG, Essential_Info

> dejpeg = __OBJECT_Function JPEG, Decode_to_Memory

> jpeg_struct = infojpeg "Grail_Logo_1995_number_7"

> logo = dejpeg "Grail_Logo_1995_number_7"

> __OBJECT_Discard JPEG

> ; hmm. out of memory I guess...

> if (logo==NULL)

> end

> endif

> ;now blit the thing out to the graphics screen

> bitBLT_form.srcleft=0

> bitBLT_form.srctop=0

> bitBLT_form.srcright=infojpeg.width

> bitBLT_form.srcbottom=infojpeg.height

> bitBLT_form.dstleft=0

> bitBLT_form.dsttop=0

> bitBLT_form.bitdepth=infojpeg.bitdepth

> __GOBJ_BitBLT bitBLT_form

> while __KEYBOARD_ReadKey==0

> {

> }

> ;free the memory allocated for the JPEG by the jpeg object

> __MMU_Free logo

> __KERNEL_Reboot ; =)

> end

> Script EXAMPLE 5

> ;--------------

> ;This script is meant to be called to ask if a certain file is a specific graphics

> ;file format.

> ;--------------

> object FILE_FORMAT

> function Creation()

> end

> function Destruction()

> end

> public function Is?(ptr filename, word type)

> return

> {

> int n

> }

> parameter type

> {

> 1,"jpeg"

> 2,"tiff"

> }

> ptr func

> word v

> ;jpeg

> if (type==JPEG)

> {

> __OBJECT_Request JPEG

> func = __OBJECT_Function JPEG, Verify

> v = func filename

> if (v==0)

> n=0

> else

> n=1

> endif

> __OBJECT_Discard JPEG

> }

> ;tiff

> if (type==TIFF)

> {

> __OBJECT_Request TIFF

> func = __OBJECT_Function TIFF, Verify

> v = func filename

> if (v==0)

> { n=0 }

> else

> { n=1 }

> endif

> __OBJECT_Discard TIFF

> }

> end

> Script EXAMPLE 6 (Full Program)

> ;--------------

> ; simple example of loading up the Quake Engine and tooling around in it....

> ;--------------

> function Creation()

> end

> function Destruction()

> end

> public function Main()

> instance PO

> {

> struct Point

> {

> word x, y, z

> word roll, pitch, yawn

> }

> struct Vector

> {

> word x, y, z

> word roll, pitch, yawn

> }

> }

> PO POV, POB, POA, POAA

> ptr mode, position

> ptr glove, glove_command

> __OBJECT_Request QUAKE_ENGINE ;we start up the engine and of course the creation function initializes it.

> mode = __OBJECT_Function QUAKE_ENGINE, Global_Mode

> position = __OBJECT_Function QUAKE_ENGINE, Point_of_View

> ; ok, switch to gods-eye mode

> mode GodsEye

> __VR_ABSTRACT_Reset

> glove = __OJBECT_Function __VR_ABSTRACT, ReadPOV

> glove_command = __OBJECT_Function __VR_ABSTRACT, ReadPOVCommand

> while ( glove_command() == NULL )

> {

> POV = glove()

> position(POV.x, POV.y, POV.z, POV.roll, POV.pitch, POV.yawn)

> }

> __OBJECT_Discard QUAKE_ENGINE

> end

> Script EXAMPLE 7 (Full Program)

> ; This is the __VR_ABSTRACT object for a hypothethical standard 4-button joystick. one button top, one trigger

> ; and two buttons on the side.

> ;

> object __VR_ABSTRACT

> common

> struct s

> {

> word x, y, z

> word roll, pitch, yawn

> }

> end

> function Creation()

> return

> {

> end

> }

> if (__JOYSTICK_Exist() == 0)

> end 0

> endif

> __JOYSTICK_Reset()

> s.x=0

> s.y=0

> s.z=0

> s.roll=0

> s.pitch=0

> s.yawn=0

> end 1

> function Destruction()

> end

> public function Reset()

> alias Creation

> end

> public function Info()

> end

> public function GetPOV()

> return

> {

> word x,y,z

> word roll, pitch, yawn

> }

> word jx, jy

> x=s.x

> y=s.y

> z=0

> roll=0

> pitch=0

> yawn=0

> (jx, jy) = __JOYSTICK_xy_Acceleration()

> x+=xj

> y+=yj

> s.x=x

> s.y=y

> end

> public function GetPOB()

> alias GetPOV

> end

> public function GetPOA()

> alias GetPOV

> end

> public function GetPOAA()

> alias GetPOV

> end

> public function Response()

> return

> {

> end

> }

> end 0

> public function Command()

> return

> {

> word button

> }

> button = __JOYSTICK_Button 1 ;the trigger button is the 2nd one on our joystick

> end

> public function CommandMatrix()

> return

> {

> word b[4]

> }

> b[1] = __JOYSTICK_Button 0

> b[2] = __JOYSTICK_Button 1

> b[3] = __JOYSTICK_Button 2

> b[4] = __JOYSTICK_Button 3

> end

> Script EXAMPLE 8

> ;

> ; Load up some objects and then leave them.

> ;

> if( __OBJECT_Verify("Generic TIFF")>0)

> {

> if(__OBJECT_Request("Generic TIFF")<0)

> {

> __OBJECT_Terminate()

> }

> __OBJECT_UnID()

> }

> if (__OBJECT_Verify("Generic PNG")>0)

> {

> if (__OBJECT_Request("Generic PNG")<0)

> {

> __OBJECT_Terminate()

> }

> __OBJECT_UnID()

> }

> Script EXAMPLE 9 (Full Program)

> ;

> function Creation()

> end

> function Destruction()

> end

> function main()

> ptr Debug, Info, Parameter, Language, Object, Decryption

> template objs

> {

> dword Internal_Build

> ptr Class_Name

> ptr Instance_Name

> ptr Associative_Name

> }

> ptr PrintVars

> (Debug, Info, Parameter, Language, Object, Decryption)=__OBJECT_Area()

> objs=object

> __OBJECT_Request __SCRIPT

> OpenWin = __OBJECT_Function __SCRIPT, TextWindow_Open

> PrintVars = __OBJECT_Function __SCRIPT, TextWindow_PrintVars

> CloseWin = __OBJECT_Function __SCRIPT, TextWindow_Close

> PrintVars "Internal Build ",objs.Internal_Build, "\n"

> __KEYBOARD_ReadKey()

> __OBJECT_Discard __SCRIPT

> end

> Script EXAMPLE 10

> ;

> `template bitBLT_form {`

> `dw srcwidth`

> `dw srcheight`

> `dw srcleft`

> `dw srctop`

> `dw srcright`

> `dw srcbottom`

> `dw srcpage/plane`

> `dw dstleft`

> `dw dsttop`

> `dw dstpage/plane`

> `dw x_type`

> `dw y_type`

> `db bitdepth`

> `}`

> `bitBLT_form yf`

> ``

> `template Normal_Visual {`

> `dw zoom_x`

> `dw zoom_y`

> `dw aspect_x`

> `dw aspect_y`

> `dd width`

> `dd height`

> `db bitdepth`

> `}`

> `Normal_Visual p`

> ``

> p.zoom_x=0

> p.zoom_y=0

> p.aspect_x=4

> p.aspect_y=3

> p.width=640

> p.height=480

> p.bitdepth=8

> __VISUAL_Request_Mode normal, higher_size, p

> ; open a graphic we know is 100x200 256colors

> yazref = __FS_LookuprefID "Yazzie_1994;7"

> yaz__FS_OpenData yazref

> yf.srcwidth=100

> yf.srcheight=200

> yf.srcleft=0

> yf.srctop=0

> yf.srcright=99

> yf.srcbottom=199

> yf.dstleft=0

> yf.dsttop=0

> yf.bitdepth=8

> __GRAPHICS_BitBLT yf

> __FS_CloseData yaz, flush

> COMMENTARY

> None yet.