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 | C O N T R O L L E R S

DESIGNER

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

DRAFTS

TOC


(a0.02)

Preface


Table of Contents

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

OverviewAn Overview of the Controller Interface
Abstract Virtual Presence
Human Virtual Presence
Mouse
Joystick
Light Pen
Tablet Pen
VR Glove
VR Head Tracker

TOC


A Controllers Interface Overview

CONCEPT | Lewis A. Sellers lsellers@usit.net

ORIGINAL DESIGN | Lewis A. Sellers lsellers@usit.net

keyboard

joystick

mouse

vr glove

vr headset controller

TOC


Abstract Virtual Presence

CONCEPT | Lewis A. Sellers lsellers@usit.net

ORIGINAL DESIGN | Lewis A. Sellers lsellers@usit.net

There are two high-level non-hardware specific VR controller interface objects. The less-detailed one is the AVPI, or Abstract Virtual Presense Interface. With this interface you have three points of reference, the Point of Vision (POV), the Point of Body (POB) and the Point of Action (POA). These are typically derived from one piece of hardware and provide a common interface that allows you to switch controller types at will (even to the bizarre) without having to rewrite your applications.

Each of the these abstract points (POV, POB, and POA) have the same set of attributes:

POINT

x, y, z

roll, pitch, yawn

VECTOR

x, y, z

roll, pitch, yawn

All are 16-bits (word) in size. They are updated by whatever hardware device you've choosen to drive the AVPI.

The Point of Vision (POV) describes where you are looking. The Point of Body (POB) describes where your body is. The Point of Action (POA) describes where you are acting upon... ie, where you are pointing your gun, etc. There is also the alternatie POA called POAA. The three points may be the same with some controllers, while others fully support them all in some fashion. If a point is not supported then you get the data for POV.

For example... If you assign a simple joystick to your AVPI then POV, POB, and POA will all be the same. Vector will be interpreted as the change in readings since the last poll. The points roll, pitch and yawn....

The AVPI also has what is called a command matrix. Simply put, this a list of all the buttons on the device. A specific joystick's device driver may or may not assign some of the buttons as command set toggles. For instance, if you have a four button joystick, one of them might be assigned as a set toggle that change the operation of all the other buttons (same as SHIFT, ALT or CTRL on the keyboard). Buttons that change state are state buttons. The others are action buttons.

timebase:

Pressure

We can also send back some form of a tactile response through this interface. While no where near as complex as the other VR controller responses it is sufficient for our purposes here. Each of the four points can recieve a feedback of four types. As to whether these are actually used depends upon your controller and it's object software. At any rate, the feedback is quantified as:

-3 extremely pleasing

-2 pleasure

-1 soft

0 no feedback

1 contact

2 pain

3 severe pain

Pain is easy. The pleasure response is harder. For better quantification you must use the human VR interface.

Interfacing

Umm... ok. How to I get this to work with my joystick or VR glove? The VR_ABSTRACT encapsulates a specific piece of hardware (or hardwares). By default Grail always loads in an object which does nothing. Should you want to use a joystick here you'd call the __OBJECT.Morph VR_ABSTRACT, "VR_ABSTRACT Joystick".

You can also write your own object... even in script. Check out the section on scripts in the kernel.doc for an example.

VR_ABSTRACT.Info

support pov, pob, poa, poaa, response, - resp, +resp

matrix sets, commands

poa swapped with poaa

VR_ABSTRACT.Reset

VR_ABSTRACT.GetPOV

x, y, z

roll, pitch, yawn

VR_ABSTRACT.GetPOB

VR_ABSTRACT.GetPOA

VR_ABSTRACT.GetPOAA

VR_ABSTRACT.ResponsePOV

VR_ABSTRACT.Command

VR_ABSTRACT.CommandMatrix

TOC


Human Virtual Presence

CONCEPT | Lewis A. Sellers lsellers@usit.net

ORIGINAL DESIGN | Lewis A. Sellers lsellers@usit.net

VR_HUMAN.

head

neck

lower torso

upper torso

left hand

right hand

left arm

right arm

left foot

right foot

left leg

right leg

....data

no.

flexions...

pressure at

feedback

data migration path

resolution

point-to-point length defination

commands

TOC


Joystick

CONCEPT | Lewis A. Sellers lsellers@usit.net

ORIGINAL DESIGN | Lewis A. Sellers lsellers@usit.net

JOYSTICK.Info

Polled or interrupt?

timebase (ns)

no. buttons

JOYSTICK.Reset

JOYSTICK.Calibration(topx, topy, centerx, centery, rightx, righty, hot_spot, warmup)

Passes the calibration settings to the JOYSTICK object including the hot_spot and warmup variance.

JOYSTICK.Exist

Does the JOYSTICK.xy routine and if it times out (goes to FFFFh) then returns a 0, else returns 1.

JOYSTICK.Button button

0= not press

1= press

2= not exist

JOYSTICK.Buttons

0= not press

1= press

2= not exist

JOYSTICK.xy

Returns the current signed x and y location of joystick.

JOYSTICK.xy_Vector

Returns the directional movement in the x and y directions as -1, 0 and 1. In script it might look like:

(x, y) = JOYSTICK.xy_Vector

JOYSTICK.xy_Acceleration

Returns the change is x and y since the last time it was checked.

TOC


Mouse

CONCEPT | Lewis A. Sellers lsellers@usit.net

ORIGINAL DESIGN | Lewis A. Sellers lsellers@usit.net

MOUSE.Info

MOUSE.Rest

MOUSE.ButtonStatus button

0= not press

1= press

2= not exist

MOUSE.xy

MOUSE.xy_Vector

MOUSE.xy_Acceleration

TOC


LIGHTPEN

CONCEPT | Lewis A. Sellers lsellers@usit.net

ORIGINAL DESIGN | Lewis A. Sellers lsellers@usit.net

The old Motorola 6845 CRT controller chips on the first IBM PC graphics cards had simple light pen support. Some cards still do. These functions directly access those ports.

LIGHTPEN.Info

LIGHTPEN.Reset

LIGHTPEN.Press

LIGHTPEN.xy

LIGHTPEN.xy_Vector

LIGHTPEN.xy_Acceleration

TOC


TABLET PEN

CONCEPT | Lewis A. Sellers lsellers@usit.net

ORIGINAL DESIGN | Lewis A. Sellers lsellers@usit.net

TABLETPEN.Info

TABLETPEN.Reset

TABLETPEN.Button

TABLETPEN.Pressure

TABLETPEN.PRESs

TABLETPEN.xy

TABLETPEN.xy_Vector

TABLETPEN.xy_Acceleration

TOC


VR Glove

CONCEPT | Lewis A. Sellers lsellers@usit.net

ORIGINAL DESIGN | Lewis A. Sellers lsellers@usit.net

VR_GLOVE

TOC


VR Head Tracker

CONCEPT | Lewis A. Sellers lsellers@usit.net

ORIGINAL DESIGN | Lewis A. Sellers lsellers@usit.net

VR_HEADTRACKER.

TOC


KEYBOARD

CONCEPT | Lewis A. Sellers lsellers@usit.net

ORIGINAL DESIGN | Lewis A. Sellers lsellers@usit.net

An IRQ1 (INT 31h) is generated by any press or release of keys on the IBM AT compat keyboard. That keys scancode is sent to port 60h (and 64h) where it is read and translated into an ascii code format. Scancode may consist of more than one byte, and thus require multiple intelligent reads to determine the specific key pressed.

A bit buffer is kept for all translated ascii keys which represents NOTPRESSED if 1 and PRESSED if 0. This is possible because IBM keyboards generate scancode at both the press AND release of a key. Each byte of a scancode is 7 bits, the 8th bit of the scancode byte representing PRESS if 0 or RELEASE if 128.

Light toggling is hardcoded into the keyboard handler. So is general toggling, and the special handling of SHIFT, ALT and CTRL keys. SHIFT, ALT and CTRL generate scancodes, but are not translated into getable ascii keycodes. A seperate bit buffer, contingous to the normal bit buffer, is kept for them. If you wish to determine if they are pressed, you must read their PRESS/RELEASE bit from the buffer.

Special handlers may be linked into the keyboard interrupt for short tasks. Very short tasks.

All keycodes are in word format.

Translate_Scancode_to_KeycodeBuffer()

Directly reads port 64h, getting scancodes into an 8 byte buffer. Once all scancodes are recieved, uses smart lookup tables to quickly getback the appropriate ascii code, store it in the keyboard buffer area before returning UNLESS the scancodes are for any of the SHIFT,ALT or CTRL keys being pressed.

If the scancode is SHIFT, ALT or CTRL their bit buffer is appropriately masked, and this routine returns.

The ascii lookup may be modified by having any of the SHIFT, ALT or CTRL keys PRESSED DOWN or if the CAPS LOCK, NUM LOCK or SHIFT LOCK are toggled ON.

All validily translated ascii codes have their PRESS or RELEASE data masked into a bit buffer. This buffer is currently 101 bits in length (16 bytes allocated) and is access via an associated 101 word long table of valid ascii keycodes.

The INT 31h which is tied to IRQ1 jumps to this routine.

A set of bit-flags are kept in a byte to determine the toggle status of all hardcoded toggled-keys. In this set of bit-flags 0 represents NOT_TOGGLED and 1 represents TOGGLED.

These bit states are flipped every time a toggle-key is PRESSED. Every time a toggle key is pressed, it is checked to see if it also has an assigned keyboard light. The light is turn ON or OFF, appropriately.

SOURCE/LIGHTS:

mov al,0edh ;change lights command

out 64h,al

nop ;wait

mov al,KEYBOARD_TOGGLE_FLAGS

and al,7 ;isolate the first three toggles

out 64h,al

Ö7Â6Â5Â4Â3Â2Â1Â0.

º not used3c3n3

ÓÄÁÄÁÄÁÄÁÄÁÒÁÒÁÒ1/2

º º ÈÍ ScrollLock light (0=OFF / 1=ON)

º ÈÍÍÍ NumLock light

ÈÍÍÍÍÍ CapsLock light

IBM KEYBOARD SCANCODE TRANSLATION MATRIX:
port data                 Shift   Ctrl    Alt
01           ESC
02           1
03           2
04           3
05           4
06           5
07           6
08           7
09           8
0A           9
0B           0
0C           -
0D           =
0E           BackSpace
0F           Tab
10           q
11           w
12           e
13           r
14           t
15           y
16           u
17           i
18           o
19           p
1A           [
1B           ]
1C           Enter
1D           Left Ctrl
1E           a
1F           s
20           d
21           f
22           g
23           h

24 j

25 k

26 l

27 ;

28 '

29 '

2A Left Shift

2B \

2C z

2D x

2E c

2F v

30 b

31 n

32 m

33 ,

34 .

35 /

36 Right Shift

37 PrtSc

38 Left Alt

39 Space Bar

3A Caps Lock

3B F1

3C F2

3D F3

3E F4

3F F5

40 F6

41 F7

42 F8

43 F9

44 F10

45 Num Lock

46 Scroll Lock

47 Home

48 Cursor Up

49 PgUp

4A Gray -

4B Cursor Left

4C (gray 5)

4D Cursor right

4E Gray +

4F End

50 Cursor Down

51 PgDn

52 Ins

53 Del

54 Sys Req

E0 1C Gray Enter

E0 1D Right Ctrl

E0 35 Gray /

37 Gray *

E0 38 Right Alt

E0 47 Gray Home

E0 48 Gray C Up

E0 49 Gray PgUp

E0 4B Gray C Left

E0 4D Gray C Right

E0 4F Gray End

E0 50 Gray C Down

E0 51 Gray PgDn

E0 52 Gray Ins

E0 53 Gray Del

57 F11

58 F12

E1 Pause

Caps Lock All asciis from 'a' to 'z' are translated to 'A' to 'Z'. All asciis from 'A' to 'Z' are translated to 'a' to 'z'. Num Lock ?

Keycode

Keycodes are generally in standard ASCII format for cross-platform compatibility reasons. This means that when a key is pressed its scancode is translated directly into ASCII before you ever see it.

Internal Keyboard Structures

dword pointer to current key from keyboard

dword last read pointer

byte ?

byte keyboard_buffersize

word keyboard_bufferlength

dword pointer to buffer

byte KEYBOARD_TOGGLE_FLAGS

bit 0=scroll

1=num

2=caps

3=insert

4=pause

word Key_Buffer[256];

dword keyboard_bitbuffer[4];

keyexist_list []

Keypress Interrupt Handlers

3 (word)Link_Keypress_to_InterruptHandler(int keycode,char *handler)

Will attempt to add a link to the keyboard handler that INT 31h (IRQ1) calls before it IRETs.

3 (void)Unlink_Keypress_from_InterruptHandler(int keypress)

Removes a key from the keyboard interrupt list.

3 (void)Unlink_All_Keypress_from_InterruptHandlers()

Changes the call in the INT 321h handler to pointer to a RET.

3 (word)Number_of_Kepress_InterruptHandlers()

Returns the no of keys monitored. There is a base minimum of 16.

KEYBOARD.Initialize

Sends commands to reset the keyboard microprocessor on IBM AT compats. If all goes well, a 1 (OK) is returned. Otherwise, a 0 (NULL)

PSUEDO SOURCE OF FUNCTION:

mov al,ffh ;reset keyboard, internal diagnostics

out 64h,al

nop ;wait

mov al,f4h ;enable keyboard,clear buffer, and send ACK

out 64h,al

nop ;wait

in al,64h

cmp al,6h ;ack?

jne nokback

nop ;no send echo-back diagnostic

mov al,0eeh

out 64h,al

nop

in al,64h

cmp al,0eeh ; if we recieve 0eeh back, then the keyboard is working.

jne nokback

;now that we know the keyboard seems to be there and functioning,

;let us set the typematic rate to something decent

mov al,0f3h ; send typematic rate & delay change command

out 64h,al

; 0=250ms

; Ö7Â6Â5Â4Â3Â2Â1Â0. 1=500ms

; º03dly3rept rateº 2=750ms

; ÓÒÁÄÁÄÁÄÁÄÁÄÁÄÁÄ1/2 / 3=1000ms

; º ÈË1/4 ÈÍÍÍÍÍÍÍÊÍ bits 0-4 the repeat rate

; º ÈÍÍÍÍÍÍÍÍÍÍÍÍ bits 5-6 initial delay before first repeat

; ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ bit 7 is always 0 \

; Value Rate Value Rate

; 0 = 30.0 0Ah = 10.0

; 1 = 26.7 0Dh = 9.2

; 2 = 24.0 10h = 7.5

; 4 = 20.0 14h = 5.0

; 8 = 15.0 1Fh = 2.0

nop ; wait

mov al,2 + 0*32 ; set the delay to 1/4-second with 24 repeats per sec.

mov al,1 ;everything went fine. return 1 (OK).

ret

nokback: ; there was a problem. return 0 (NULL).

xor al,al

ret

KEYBOARD.Deinitialize

Doesn't do anything on IBM PCs clones, but provided for completeness.

KEYBOARD.Get_BufferSize

Returns KEYBOARD_BUFFER_SIZE, from which the buffer size is computed by 2^n. Ranges from 4 to 15, so buffer size is from 16 to 32768. Default is 32 characters.

KEYBOARD.Set_BufferSize length

Sets KEYBOARD_BUFFERSIZE as 2^bs. Valid bitmag from 4 to 15.

KEYBOARD.ClearBuffer

Clears all keys in the key buffer. Makes position equal to lastread position.

KEYBOARD.WriteKey

Puts a key (back?) into keyboard buffer. It has it's uses.

KEYBOARD.ReadKey

Returns the word at the current last-read buffer position unless the current buffer position is equal to it. If a keycode is available it also increases the last-read pointer ahead (by a word). cf. getch().

KEYBOARD.ReadKey_Monitor

Same as readkey() but the pointer is not advanced. cf. kbhit().

KEYBOARD.KeyExist keycode

Looks up the keycode in the KeyExists list and returns a 1 if the key exists on the users keyboard. You of course get a 0 if it can't be found, or its equivilent. The Open-Apple for instances is rarely found on an IBM PC Platform.

KEYBOARD.KeyStatus keycode

Looks up (REP SCAS) the asciikeycode's position in the keyboard bit buffer, then retrieves that bit. If the bit is 0, the key in question is currently down. If it is 1, it is not being pressed. Also looks in the key existance

KEYBOARD.KeyStatus_Direct bitposition

A quicker version of KeyStatus. If you have a table listing the ordering of ascii keycodes internally in the MOSAPI (which should be the same on most all platforms) you can skip the lookup table part and directly grab the appropriate bit from the bit buffer.

KEYBOARD.ToggleStatus key

Returns a 0 if key is not toggled, a 1 if toggled, and a 2 if it does not toggle.

KEYBOARD.LightStatus key

Returns a 1 if light is on, a 0 if light is off and a 2 if no light.

KEYBOARD.xy

KEYBOARD.xy_Vector

KEYBOARD.xy_Acceleration