═══ 1. Title Page ═══ Oberon for OS/2 User's Guide Release 4.0-0.6e (February 96) (Unregistered version) Daniel Steiner Copyright 1994-1996, D. Steiner ═══ 2. Disclaimer and legal issues ═══ THE AUTHOR D.STEINER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. Syntax Font, Copyright 1968 Linotype AG Syntax is a registered trademark of Linotype AG. The Syntax font is owned and used by permission of Linotype AG. RASTER DATA DESCRIBING THE SYNTAX FONT IS SUPPLIED WITH THIS RELEASE OF OBERON AND MAY BE USED ONLY IN CONJUNCTION WITH THE OBERON SOFTWARE. ANY OTHER USE OF THE SYNTAX FONT REQUIRES A LICENSE FROM LINOTYPE AG. PostScript versions of the fonts in the Syntax family are available from Linotype, Inc. and its subsidiaries. Oberon and Oberon for Windows are trademarks of EidgenФssische Technische Hochschule, ZБrich Microsoft, MS and MS-DOS are registered trademarks of Microsoft Corporation. NT, Win32, Win32s, Windows and Windows NT are trademarks of Microsoft Corporation. IBM is a registered trademark of International Business Machines Corporation. OS/2 is registered trademark of International Business Machines Corporation. Intel is a registered trademark and i486 is a trademark of Intel Corporation. ═══ 3. Introduction ═══ Oberon for OS/2 is an implementation of Oberon for IBM OS/2 2.1 and OS/2 Warp 3 operating system. Both the programming language Oberon-2 and the Oberon System have been implemented. For a complete description of the language and the system, the following books are recommended: N. Wirth and M. Reiser: Programming in Oberon. Steps beyond Pascal and Modula_2 H. MФssenbФck: Object-Oriented Programming in Oberon-2 H. MФssenbФck: Objektorientierte Programmierung in Oberon-2 M. Reiser: The Oberon System. User Guide and Programmer's Manual N. Wirth and J. Gutknecht: Project Oberon. The Design of an Operating System and Compiler The Oberon-2 language reference is also available as on-line documentation: Oberon-2 Report The original Oberon implementation is an operating system running on a proprietary hardware, the Ceres workstation. Oberon for OS/2, however, is not an operating system but runs as a PM application. The screen output of the Ceres workstation is shown in a PM window. This window can be controlled by the Presentation Manager, i.e. it can be moved or iconized. The size and position of the Oberon Window can be optionally specified on the command line. If the size is not specified the Oberon window covers the entire screen area. If the position is not specified the Oberon window is centered on the screen. The size of the virtual Ceres screen is the size of the client area of the Oberon window, which is currently not exactly the size specified on the command line, as that size specifies the size of the frame window and not the one of the client window (subject to change in future releases) The Oberon user interface was designed with a large bitmap display in mind. Oberon works best with a display of 1024 by 768 pixels or bigger. However, Oberon for OS/2 will run with any size display, but working with VGA resolution is far from optimum. ═══ 3.1. Bug Reports ═══ Serious problems or bug reports can be mailed to daniel.steiner@cch.cerberus.ch or sent to Daniel Steiner Meienbergstr. 81 CH-8645 Jona Switzerland. Please try to be as specific and concise as possible, since this makes processing of messages faster and easier. You should also mention the version number and host operating system you use (just copy the line that appears in the log viewer when Oberon is started). Please allow one week for answers. ═══ 4. Installation and Startup ═══ See the Readme file for instructions on how to install Oberon. The floppy disk contains three files oberonv4.exe, install.cmd and Readme.Txt. See Readme.Txt for further instructions. ═══ 4.1. Starting Oberon ═══ Oberon for OS/2 is started with the following command syntax: oberon [-h heapsize-in-MB] [-x module command] [-b bootfile-name] [-i ini-file] [-t] [-l logfile] [-g ] where o heapsize-in-MB is the size of the allocated Oberon heap in megabytes (default: -h 4) o the command module.command is executed (default: -x Oberon Loop) o bootfile-name is the name of the boot file (default: -b Oberon.Hex) The boot file must be in the same directory as oberon.exe. o ini-file is the name of a file that is used to store configuration data (default: oberon.ini), see description of module Registry. If no explicit path is given, the file is searched for in the following directories: (1) current directory, (2) OS/2 system directory, (3) in all directories listed in the PATH environment variable. o Option t means "no title bar". The Oberon window is maximized such that the client area of the window covers the whole screen, i.e. the title bar of the window is not visible. o logfile is the name of a file that receives all output written with the module Console. Console is a useful module for low-level debug output. If this option is not specified, output from module Console is lost. o geometry has the following syntax and specifies the size and optional position of the Oberon window: X[XX]. (e.g. -g 800x600) If the size is specified the Oberon window can no longer be resized or maximized. If the size is specified but not the position than the Oberon window will be centered on screen. ═══ 4.2. Quitting Oberon ═══ If an Oberon command does not terminate (e.g. hangs in a never-ending loop), there is currently no way of stopping that command. The Oberon application must be "killed" and restarted. It is planned that future versions support the cancellation of a command with Ctrl-C. The command System.Quit terminates the Oberon application. This is the normal way to exit Oberon for OS/2. Alternatively, the application can be terminated by choosing "Close" in the application window's system menu or by using the keyboard accelerator Alt-F4. ═══ 5. Release Notes ═══ Restrictions and Known Bugs in this Release o Vectorfonts are not yet fully supported. o Only rudimentary printer support. o Printing causes trouble on some configurations. o Modules Diskette, Backup, and Tar are not yet implemented. o The Oberon window should be the topmost window on the screen, or scrolling may not work correctly. o A display mode with 16 or 256 colors is required. o color palette manager is not supported. Changes since Release 4.0-0.6a o new installation script o the size of executable has been reduced o new method for object finalisation o rudimentary support for printing to any OS/2 default printer o rudimentary support for Oberon GPI fonts o $filedir.$$$ is now written back to disk which increases loading of the system. o DOS filename may be upto 32 characters long. Changes since Release 4.0-0.6 o option -t is now implementated. o About menu is now located in the system menu. o system.exe has been renamed in OBERONV4.EXE. o better vector font support. o Compiler.Compile supports now option which effects all modules compiled but must specified only once after the command Compiler.Compile on the same command line. o Compiler and loader support now identifiers with length upto 40 characters. Changes since Release 4.0-0.5 o rudimentary support for OS/2 vectorfonts have been included. o unregistered version have now the words "unregistered version" in the window title. o the major and minor number of the operating system is written to the log window o UserGuide and Oberon-2 report are no longer available as Oberon documents. They are now included in OS/2 INF format. o size and position of the Oberon window may be specified on the command line. o when compiling ASCII-files the compiler displays errors and warnings in the format (col/line) o new compiler option /w to suppress warnings. o new compiler option /e to enable language extension (default off) - underscore in identifier allowed. - identifier may have a length upto 40 characters. o Display, PM32 and Fonts have been improved. Changes since Release 4.0-0.4 o Kernel.SetClock is now implemented o changing drives from within OS2oberon is now possible Changes since Release 4.0-0.3 o Analyzer is now part of the distribution o some bugs in OBERON.EXE has been corrected o Implementation of Display1 is now included o Bugs in FileDir and Files corrected o Status of OS2oberon has been changed to Shareware. Changes since Release 4.0-0.1 o OS/2 system calling linkage is used to access OS/2 functions o New command System.CreateDirectory added. o System.Directory writes full path names of files instead of just the file names. o The file translation table $filedir.$$$ will not be deleted in a directory that has the read-only attribute set. This allows for network installations of Oberon for Windows where the system files reside on a server directory that may be shared. o Small changes in appearance and handling of parcs. See Edit.Guide.Text. o A service for permanent storage of configuration data has been introduced, named the Registry. The registry essentially is an interface to an "ini-file" that can be specified at system startup (option -i, see above). The registry can be modified using the commands System.Set and System.Get. o The environment variable OBERONDIRS is no longer supported. Instead, the search path for Oberon files is contained in the registry. Use the command System.Set System Directories := "Directory1;Directory2;..." ~ instead to specify additional directories in the search path. The Oberon directory, it's subdirectory "Fonts" and the current working directory do not have to be listed, they are searched automatically (see description of Registry below). o The environment variable FONTSUBST is no longer supported. The information about printer font substitution is contained in the registry. Use the command System.Set System PrinterFonts := "Font1 Substitution1; Font2 Substitution 2;...." ~ instead to specify printer font substitution. o Font substitution on the screen is stored in the registry as well, see Font Substitution on the Screen below. o The following text files can contain predefined menu-texts that are used instead of the standard menu string if present: Edit.Menu.Text (Edit.Open), Log.Menu.Text (System.OpenLog), System.Menu.Text (System.Open), and Hex.Menu.Text (Hex.Open). Note: The texts in these files must not contain elements or font styles that are larger than the default system font, otherwise the menu text is clipped away and will not be visible. o A simple but convenient utility named StatusViewer displays the name of the current directory in it's title bar. See StatusViewer.Mod. ═══ 6. Differences to the Original Oberon ═══ This section is about the differences to the original Oberon system from a user's point of view. The original Oberon system is described in The Oberon System by M. Reiser. The differences in module interfaces are described in the next section. ═══ 6.1. Printing ═══ In the original Oberon on Ceres, the Commands Edit.Print, Draw.Print etc. accept a server name as the first Parameter (usually called Pluto). The server's printer is then used to print the document. Oberon for OS/2 supports now printing to the default printer object with the restriction that some special fonts (eg. Elektra) currently are not supported. The Oberon fonts Syntax and Syndor are not available as printer fonts. They are substituted by Postscript fonts instead. By default, both fonts are substituted by the Postscript font Helvetica. This default mapping can be changed by defining the Key PrinterFonts in the registry section System (see below). ═══ 6.2. Registry ═══ Oberon for OS/2 has a mechanism to store configuration data permanently. The permanent storage is called the registry. The registry is structured hierarchically into sections and keys. Each section can be thought of as a dictionary that associates a value with a key. Module Registry provides a program interface to the registry (see below). The user interface is embodied in the commands System.Set and System.Get. System.Set ( ^ | section key := [ value ] ) Enter a section and key in the registry and associate a value with it. If a value is not given, the entry for the given section and key is removed from the registry. Section, key, and value may be either names or strings. System.Get ( ^ | section [ key ] ) Inspect the value of a given section and key in the registry. If a key is not given, all keys contained in section are listed together with their associated values. Section and key may be either names or strings. Currently, there are two registry sections supported by Oberon for OS/2. The section System contains system-specific settings. The section Fontmap contains a list of screen fonts that are to be substituted by other fonts (see Font Substitution below). The keys of section System are Key Value DefaultFont A font name. The font will be used as the default font the next time Oberon is started. E.g.: System.Set System DefaultFont := Syntax8.Scn.Fnt PrinterFonts A list of pairs of the form Font Substitution { ";" Font Substitution }. When printing a document, the fonts of the family Font are substituted with the font Substitution. Changes will take effect upon the next time Oberon is started. See the description of Module Printer for more details. E.g.: If your system has a Postscript font Helvetica installed, the command System.Set System PrinterFonts := "Syntax Helvetica" will configure Oberon to print Syntax fonts as Helvetica. Directories A list of absolute path names, separated by semicolons. When Oberon opens a file and no explicit path is given, it looks first in the current directory, then in the Oberon directory, and then in all the directories listed here. ═══ 6.3. Font Substitution on the Screen ═══ The Oberon for OS/2 font subsystem allows the user to map specific fonts onto different fonts. It may for example be convenient to map Syntax10.Scn.Fnt to Syntax8.Scn.Fnt on VGA displays. The font mapping table is stored in the registry. If a section Fontmap is present, the keys of the section are interpreted as font names and the associated values are the substituted fonts. You can for example substitute Syntax8.Scn.Fnt for Syntax10.Scn.Fnt by issuing the command System.Set Fontmap Syntax10.Scn.Fnt := Syntax8.Scn.Fnt~. The mapping will be stored permanently in the registry. You must restart Oberon for OS/2 for the changes to become effective. To inspect all mappings, execute the command System.Get Fontmap ~. To remove a particular mapping, execute System.Set Fontmap Syntax10.Scn.Fnt := ~. See the description of commands System.Set and System.Get for detailed information. Note: This feature is supposed to mend problems on displays with small resolutions like VGA screens, where one could substitute the font Syntax10.Scn.Fnt by Syntax8.Scn.Fnt, for example. The fonts are substituted on the display only, but not when printed. Moreover, the metrics of parcs are not affected by font substitution. It is even possible to use Postscript font for substitution. For example System.Set Fontmap Syntax10.Scn.Fnt := Times New Roman10.Scn.Fnt~. ═══ 6.4. Oberon Files vs. DOS Files ═══ Oberon for OS/2 distinguishes between Oberon files and DOS files. In order to support 32 character file names, Oberon files contain a small header of information containing their file name (see the description of module Files for further details). DOS files do not contain such a header. To specify a DOS file, you must prepend an ampersand character "&" to the file name proper. For example, to edit the DOS ASCII test file c:\autoexec.bat, you will have to execute the command Edit.Open c:\&autoexec.bat . To store the file in plain ascii format, mark the viewer containing the text (its name in the title bar is c:\&autoexec.bat) and execute EditTools.StoreAscii *. Files from Oberon implementations other than Oberon for OS/2 or Oberon for Windows or DOSOberon do not contain that header and are treated like DOS files. To "import" such files into Oberon for OS/2, you would execute System.CopyFiles Drive:\Path\&Filename.Ext => Drive:\Path\Filename.Ext ~. This inserts the header into the file. To remove the header, just execute System.CopyFiles Drive:\Path\Filename.Ext => Drive:\Path\&Filename.Ext ~. If you copy Oberon files to floppy with the OS/2 or DOS copy command and read them in on a non-OS/2 Oberon, the file will still contain a header and you will see it when you open the file with Edit.Open (the header starts with the letters "oB"). To copy files on floppy correctly, use the command System.CopyFiles and specify A or B as the destination drive. For the sake of convenience, file names on floppies are always interpreted as DOS files, it is not necessary to prepend the "&" character. When files are stored on floppy disks using either the Backup or Tar utility, the header is ommitted. The files can be read by any other Oberon implementation that supports these tools. ═══ 6.5. Support for Multiple Directories ═══ The original Oberon implementation uses a flat file directory, i.e. does not support subdirectories. Oberon for OS/2 allows to open files from any directory, including floppy disks. For each directory that contains Oberon files, a translation table is built that associates 32 character Oberon file name to DOS file names. These directories containing Oberon files must be specified in the registry section System under the key name Directories. When Oberon opens a file and no explicit path is given, it looks first in the current directory and then in all the directories listed under the registry entry System Directories. The translation tables are stored in the respective directories. The file name for the tables is "$FILEDIR.$$$". If ever the translation table becomes inconsistent, it is sufficient to delete these files and restart Oberon. The tables will be built up from scratch using the information found in the file headers of Oberon files. See the description of module Files for further details. Directories on floppy disks have no translation table and the files in such a directory do not have a header. When storing a file on floppy, the file name is simply truncated to conform to the "eight plus three" naming convention. Only paths that start with "A:" or "B:" are supposed to refer to a floppy disk. ═══ 6.6. Support for systems with two-button mice ═══ For PCs with a two button mouse, the Ctrl-key of the PC keyboard emulates the middle mouse button. The first time Oberon for OS/2 detects a middle-mouse-key-down event, this emulation is disabled. ═══ 7. Module Reference ═══ This section describes differences to the standard modules described in The Oberon System by M. Reiser. It also describes modules unique to Oberon for OS/2. ═══ 7.1. Standard Modules ═══ ═══ 7.1.1. Files ═══ The interface to the file system is identical with that of the original Oberon system. However, due to the underlying operating system, some differences need to be discussed. Oberon file names may be as long as 32 characters and may contain more than one dot, whereas on the DOS FAT file system names are restricted to the well-known eight plus three characters with a single dot between the file name and the file name extension. Although OS/2 supports longer filename and filenames with more than one dot on HPFS partition it does not support case-sensitive filenames and therefore Oberon for OS/2 still uses the same mapping for HPFS partition as for DOS FAT file system. In order to be compatible with other Oberon implementations, Oberon for OS/2 maintains a translation table that maps Oberon file names to DOS file names. This table is kept in memory while Oberon is running and is written to disk when the application is exited. Since this table is of extreme importance for the proper working of Oberon, it is stored again in a distributed manner: Files that are created by Oberon have a 34 byte header stored 'inside' the file itself. The header consists of a two byte tag and the 32 byte Oberon file name. When the cached translation table is not found at system startup, or if the cached table is found to be inconsistent, it is newly built up by scanning all files in the directory and extracting the Oberon file name from their headers. This header is never 'seen' from inside Oberon. Sometimes one would like to create regular OS/2 (or DOS) files or open files that have not been created by Oberon for OS/2. To distinguish OS/2 files from Oberon files, an ampersand character "&" is prefixed to the file name proper. The ampersand itself is not part of the file name, but just directs the Files module to treat the file as a DOS file, i.e. expecting no header when the file is opened and writing no header when the file is registered. For example, the autoexec.bat file could be opened for editing with the command Edit.Open c:\&autoexec.bat and stored with the command EditTools.WriteAscii *. When files are stored on floppy disks using either the Backup or Tar utility, the header is ommitted. The files can be read by any other Oberon implementation that supports these tools. This way of integrating OS/2 files into Oberon for OS/2 has proven to be most convenient. However, it has some drawbacks, too. Files created on Oberon for OS/2 are not binary compatible with files created on other implementations of Oberon. E.g. files created on a Unix implementation that are downloaded electronically to either a FAT or HPFS directory do not have a header. They must be opened with the ampersand character prefixed to their file name. It is possible to "import" such files with a simple trick: use the command System.CopyFiles &Filename => Filename ~ to prepend a header to the file. From this point, it is possible to open the file without the "&" prefix. Files created with DosOberon or Oberon for Windows do have the same kind of header and can be opened without the prefix. Oberon for OS/2 allows to open files from any directory, including floppy disks. Translation tables for directories are built on demand. For faster startup, some translation tables are cached on disk when Oberon is exited. These directories must be specified in the Registry. When Oberon starts up, it builds the translation table for these directories, using the cached tables if available. After the system has successfully booted, the cached translation tables are destroyed, such that after a system crash they are rebuilt from scratch. Upon normal exit of Oberon, the translation tables of all directories specified in the Registry are written to disk. The files that contain this table have the name "$FILEDIR.$$$". If ever the translation table becomes inconsistent, it is sufficient to delete these files and restart Oberon. Directories on floppy disks have no translation table and the files in such a directory do not have a header. When storing a file on floppy, the file name is simply truncated to conform to the "eight plus three" naming convention. Only paths that start with "A:" or "B:" are supposed to refer to a floppy disk. Following a summary of differences to the original Oberon implementation: Open (name: ARRAY OF CHAR): File; New (name: ARRAY OF CHAR): File; Delete (name: ARRAY OF CHAR; VAR res: INTEGER); Rename (old, new: ARRAY OF CHAR; VAR res: INTEGER); Filenames may consist of a drive specifier, a path, and a file name. An ampersand character previous to the first character of the file name specifies a OS/2 file. Rename fails if either the drive specifier or the path of old and new do not match. ═══ 7.1.2. Display ═══ o Procedures DefCC, DefCP, DrawCX, FadeCX, InitCC, InitCP, SetCursor are not implemented. o Procedure SetMode inspects only set element {2}, i.e. SetMode can only be used to switch between black-on-white and white-on-black mode o Map returns 0 (the display bitmap is not directly accessible). o The cursor is controlled by OS/2 Presentation manager and is still active when a command is executing. o NewPattern: image[1] defines the bottom line of the pattern. image[0] is not used. o CopyPatternC, ReplPatternC, ReplConstC, CopyBlockC, and DotC take a frame parameter F against which the display output is clipped. ReplPatternC also takes a "pin point" or "pattern origin" xp, yp to align pattern output. ═══ 7.1.3. Input ═══ o Input.Time() returns 'ticks' in increments of 1/Input.TimeUnit th of seconds (1/1000th of seconds). ═══ 7.1.4. Special Keys ═══ Some special keys on the Ceres keyboard are mapped to the PC keyboard as follows: ┌──────────────────────────────────────────────────────────────────┐ │PC Keyboard Ceres Keyboard Function │ ├──────────────────────────────────────────────────────────────────┤ │Backspace DEL │ ├──────────────────────────────────────────────────────────────────┤ │Delete - delete right in text frames │ ├──────────────────────────────────────────────────────────────────┤ │F1 SETUP mark viewer │ ├──────────────────────────────────────────────────────────────────┤ │F9 PF1 white on black background │ ├──────────────────────────────────────────────────────────────────┤ │F10 PF2 minimize window if no titlebar is │ │ visible │ ├──────────────────────────────────────────────────────────────────┤ │F11 PF3 black on white background │ ├──────────────────────────────────────────────────────────────────┤ │F12 - set default color palette │ ├──────────────────────────────────────────────────────────────────┤ │Ctrl-Enter LINE FEED line feed │ ├──────────────────────────────────────────────────────────────────┤ │Home - redraw screen │ ├──────────────────────────────────────────────────────────────────┤ │Pause BREAK │ ├──────────────────────────────────────────────────────────────────┤ │Shift-Pause Shift-Break │ ├──────────────────────────────────────────────────────────────────┤ │F2 No Scroll refresh in Draw │ ├──────────────────────────────────────────────────────────────────┤ │Ctrl-F2 Ctrl-No Scroll │ └──────────────────────────────────────────────────────────────────┘ For systems with a two button mouse, the Ctrl-key of the PC keyboard emulates the middle mouse button. ═══ 7.1.5. Fonts ═══ Postscript fonts are supported in a transparent way. Fonts.This(name) also loads Postscript fonts. name has the following syntax: name = Family size styles ".Scn.Fnt" E.g., Fonts.This("Helvetica43bi.Scn.Fnt") returns the font "Helvetica" in boldface and italics and in 43 pixels size. ═══ 7.1.6. Texts ═══ Some minor changes have been done in the Scanner to allow for reading of file names with drive and path specifiers. The syntax of legal tokens of class Name is: Name = ["&"] NamePart { "." NamePart }. NamePart = (letter | "." | "\") { letter | digit | "\" | ":" | "&" }. A single "&" character is of class Char. ═══ 7.1.7. Printer ═══ The Oberon fonts Syntax and Syndor are not available as printer fonts. They are substituted by Postscript fonts instead. By default, both fonts are substituted by the Postscript font Helvetica. This default mapping can be changed by defining the Key PrinterFonts in the registry section System. PageHeight and PageWidth are only valid after a call to Printer.Open. They specify the page size in 300 dpi pixels. UseListFont(name) has no effect. GetChar(font, ch, dx, x, y, w, h) returns the printer metrics of a character in 300 dpi. In Open(name, user, password), the parameters are ignored. In Page(nofcopies), the parameter is ignored. Exactly one page is sent to the printer. ═══ 7.1.8. System ═══ The command Quit leaves Oberon. The command ChangeDirectory ( "^" | newdir ) changes the current directory. The command CreateDirectory ( "^" | newDir ) creates a new directory newDir. The command Directory ([path]template["/d"] | "^") accepts a path specifier in front of the template. All Oberon files in the directory viewer are listed alphabetically, followed by the DOS files. Option /d also lists the DOS file name of an Oberon file. System.Open looks for a text with name System.Menu.Text. If it is available, it is displayed in the menu frame instead of the standard menu text. This way it is possible to configure the menu string shown in viewers opened with System.Open, e.g. the menu can also contain text elements like PopupElems or MenuElems. Note: the hight of the menu frame is not adapted to the text displayed, i.e. if the text is too large to fit into the menu frame, it is clipped and only a black bar is visible. The commands System.Set and System.Get serve to store values in the registry and to inspect the contents of the registry ═══ 7.1.9. Types ═══ o Interface module to the type system. Necessary to implement persistent objects. ═══ 7.1.10. Oberon ═══ o Time() returns Input.Time() ═══ 7.1.11. Kernel ═══ GC may be called at any time, since local pointers on the stack are used as roots during the mark phase of the garbage collection. Function Explanation LoadLibrary(name: ARRAY OF CHAR) loads the library (DLL) with name. Returns a handle to the library that can be used calling GetAdr. Calls the OS/2 API function DosLoadModule. FreeLibrary(lib: LONGINT) calls the OS/2 API function DosFreeModule. GetAdr(lib: LONGINT; symbol: ARRAY OF CHAR; VAR adr: LONGINT) returns in adr the address of the exported name symbol in the library given by lib. Calls the OS/2 API function DosQueryProcAddr. GetAdrByOrd(lib: LONGINT; ordinal: LONGINT; VAR adr: LONGINT) returns in adr the address of the exported ordinal symbol in the library given by lib. Calls the OS/2 API function DosQueryProcAddr. ═══ 7.2. Modules unique to Oberon for OS/2 ═══ ═══ 7.2.1. Registry ═══ Module Registry is an interface to the initialization file specified at startup time. It serves to store configuration data for the system and applications. The registry is structured hierarchically into sections and keys. Sections may contain an arbitrary number of keys. To each (section, key) pair, a value is associated. DEFINITION Registry; CONST Done = 0; NotFound = 2; RegistryNotFound = 1; TYPE EntryHandler = PROCEDURE (key, value: ARRAY OF CHAR); VAR res: INTEGER; res = NotFound: either a section or a key specified is not contained in the registry. res = RegistryNotFound: no initialization file was given at startup time. PROCEDURE Get (section, key: ARRAY OF CHAR; VAR value: ARRAY OF CHAR); Retrieve the value associated with a (section, key) pair. PROCEDURE Set (section, key, value: ARRAY OF CHAR); Associate a value with the pair (section, key) and store it in the registry. If value = "", an existing value is deleted and the (section, key) pair is removed from the registry. PROCEDURE Enumerate (section: ARRAY OF CHAR; handler: EntryHandler); Enumerate all keys and their associated value for a given section. For each key found in the section, the handler is called END Registry. The user interface to the registry is provided by means of the commands System.Set and System.Get. ═══ 7.2.2. Configuration ═══ At system startup, the module System searches a module Configuration and loads it if present. The module is loaded before any viewers have been opened. If the module is present, the system does not open the log viewer and system tool. Instead, the module body of Configuration is responsible to initialize the display. The module can furthermore do any custom initializations. If a module Configuration can not be found, the log viewer and system tool are opened normally. A minimal configuration module would therefore be: MODULE Configuration; IMPORT Oberon, MenuViewers, TextFrames; CONST LogMenu = "System.Close ...."; StandardMenu = "System.Close ...."; VAR X, Y: INTEGER; V: MenuViewers.Viewer; BEGIN Oberon.AllocateSystemViewer(0, X, Y); V := MenuViewers.New(TextFrames.NewMenu("System.Log", LogMenu), TextFrames.NewText(Oberon.Log, 0), TextFrames.menuH, X, Y); Oberon.AllocateSystemViewer(0, X, Y); V := MenuViewers.New( TextFrames.NewMenu("System.Tool", StandardMenu), TextFrames.NewText(TextFrames.Text("System.Tool"), 0), TextFrames.menuH, X, Y); END Configuration. ═══ 8. The Compiler ═══ The Compiler implements Oberon-2 as defined in the language report. This section describes system specific topics. ═══ 8.1. Data Representation and Alignment ═══ The following table shows the internal representation of data types in OS2Oberon: data type internal representation SHORTINT 1 Byte signed CHAR, BYTE 1 Byte unsigned BOOLEAN 1 Byte unsigned (0 = FALSE, 1 = TRUE) INTEGER 2 Bytes signed LONGINT 4 Bytes signed SET 4 Bytes ({0} = 1) PointerType 4 Bytes (NIL = 0) ProcedureType 4 Bytes (NIL = 0) REAL 4 Bytes IEEE-format (754-1985) LONGREAL 8 Bytes IEEE-format (754-1985) Variable addresses, record field offsets and record sizes are always aligned to a multiple of the type's base. The base of an unstructured type is the type's size, the base of an array is the base of the element type and the base of a record type is the maximum base of its field types. ═══ 8.2. Module SYSTEM ═══ The module SYSTEM provides some low level operations specific to this particular Oberon implementation. It provides the following functions and procedures. v stands for a variable, a, n and x for expressions, and T for a type. Function procedures: Name Argument types Result type Meaning ADR(v) v: any type LONGINT address of variable v BIT(a, n) a: LONGINT BOOLEAN n IN Mem[a] n: integer type (if a MOD 4 = 0 & 0 <= n <= 31) CC(n) n: integer constant BOOLEAN icc n (if n < 16) fcc n MOD 16 (if n >= 16) LSH(x, n) x, n: integer type LONGINT logical shift ROT(x, n) x: integer type, type of x rotation BYTE, CHAR VAL(T, x) T, x: any type T x interpreted as of type T The function SIZE remained in the language as defined in [1]. SIZE(T) returns the number of bytes required for type T. Note, SYSTEM.VAL neither produces any code for conversions nor performs any compile time checks but forces the compiler to interpret the type of an expression differently. Proper procedures: Name Argument types Meaning GET(a, v) a: LONGINT v := Mem[a] v: any basic type GETREG(n, v) n: integer constant v := * see below v: any basic type PUT(a, x) a: LONGINT Mem[a] := x x: any basic type PUTREG(n, x) n: integer constant * := x see below x: any basic type MOVE(a0, a1, n) a0,a1: integer type move n bytes from address a0 to a1 n: integer type, n> 0 NEW(v, n) v: any pointer type allocate storage block of n bytes and n: integer type assign its address to v The numbering of the registers in GETREG(n, v) and PUTREG(n, v) is defined in the table below. The size of v determines the size of the register, i.e. GETREG(0, ch), where ch is of type CHAR, reads the contents of AL. If v is a constant, the register is taken to be 32 bits. The function CC(n) is not implemented. Numbering of 80x86 registers: n register n register 0 EAX / AX / AL 4 ESP / SP / AH 1 ECX / CX / CL 5 EBP / BP / CH 2 EDX / DX / DL 6 ESI / SI / DH 3 EBX / BX / BL 7 EDI / DI / DL Types: No representation of values is specified. Instead, certain compatibility rules with other types are given: BYTE: 1. BYTE is compatible with CHAR and SHORTINT. 2. if a formal VAR-parameter is of type ARRAY OF BYTE, then the corresponding actual parameter may be of any type. PTR: 1. variables of type PTR are compatible with any pointer type. 2. VAR-parameter of type PTR contain the static type of the actual parameter upon procedure entry (to allow for runtime type checks). Code procedures The compiler allows for inline expanded "assembly" procedures. The syntax for code procedures is PROCEDURE "-" ident [FormalPars] { byte } ";" When the compiler translates a call to a code procedure, the parameters are evaluated and pushed onto the stack (from right to left). The last parameter in the parameter list can be addressed with 0[ESP]. The bytes specified are then inlined, and finally the stack pointer is reset. Code procedures must not be exported. ═══ 9. Calling OS/2 API and DLL functions from Oberon Programs ═══ It is possible to call any 32-bit functions in a DLL or most of OS/2 API functions from within Oberon. The following section gives a short overview. Currently the kernel does not support multithreading. More details are only available for registered users ═══ 9.1. Overview ═══ This is done by declaring a procedure variable for each API function to call and initialising it with the address of the respective API function. The address is determined by calling the procedure Kernel.GetAdr. The following example demonstrates how this is done: VAR lib: LONGINT; MyBox: PROCEDURE [1](owner, text, title, style: LONGINT): LONGINT; ... BEGIN lib := Kernel.LoadLibrary("mydll"); (* get handle to mydll.dll *) Kernel.GetAdr(lib, "MyProc", SYSTEM.VAL(LONGINT, MyBox)); (* get address of MyProc *) ... Kernel.LoadLibrary calls the OS/2 DosLoadModule API function, and Kernel.GetAdr essentially calls DosQueryProcAddr. With this simple mechanism it is possible to call any API function in any DLL. A few things must be paid attention to. o All parameters must have 32-bit size. o Return values are 32-bit. o For most OS/2 API it is necessary to specify OS/2 system calling convention (PROCEDURE[1]). Special care must be taken when using Oberon procedures as callback functions. The OS/2 calling convention specifies that EBX, ESI and EDI are callee-saved registers and that the called procedure must not cleanup the stack. The Oberon compiler saves no registers, thus the first action in a callback procedure must be to save these three registers, and to restore them just before the procedure returns. E.g.: PROCEDURE + MyCallback (...); VAR EBX, ESI, EDI: LONGINT; BEGIN SYSTEM.GETREG(3, EBX); SYSTEM.GETREG(6, ESI); SYSTEM.GETREG(7, EDI); .... SYSTEM.PUTREG(3, EBX); SYSTEM.PUTREG(6, ESI); SYSTEM.PUTREG(7, EDI); END MyCallback; If you need to access the OS/2 API you should have the OS/2 programming toolkit and sufficient OS/2 programming knowledge. MORE INFORMATION ARE AVAILABLE ONLY FOR REGISTERED USERS ═══ ═══ Oberon and Oberon for Windows are trademarks of EidgenФssische Technische Hochschule, ZБrich ═══ ═══ OS/2 and Warp are registered trademark of International Business Machines Corporation. ═══ ═══ Addison Wesley, 1992, ISBN 0_201_56543_9 Tutorial for the Oberon programming language and concise language reference. ═══ ═══ Springer-Verlag, 1993, ISBN 3-540-56411-X Covers the basic concepts of OOP, shows typical application patterns, and gives useful design hints. Presents the design and implementation of an object-oriented window system with an integrated text and graphics editor. Contains Oberon-2 language definition. ═══ ═══ Springer-Verlag, 1993, ISBN 3-540-55690-7 German version of Object-Oriented Programming in Oberon-2 ═══ ═══ Addison Wesley, 1991, ISBN 0_201_54422_9 User manual for the Oberon programming environment and reference for the standard module library. Includes working examples of how to extend the Oberon system with new commands and frame classes. ═══ ═══ Addison Wesley, 1992, ISBN 0_201_54428_8 Program listings with explanations for the whole Oberon system, including the compiler for NS32000.