ð‡Syntax10.Scn.FntðÿÿÿÀGWà¥ParcElemsAllocà®ÝðŠ à‰Syntax24m.Scn.FntSyntax14.Scn.FntKðÿÿÿÀGWà¥à®ÝðŠ à‰Syntax14b.Scn.FntSyntax12b.Scn.FntîÿÿÿÀGWीÊàäËðŠ à‰Syntax12.Scn.FntˆðÿÿÿÀGWà¥à®ÝðŠ à‰îÿÿÿÀGWीÊàäËðŠ à‰ŽðÿÿÿÀGWà¥à®ÝðŠ à‰T¸Syntax14i.Scn.FntB#ÃAò4N6KCJC% 9 R3ðÿÿÿÀGWà¥à®ÝðŠ à‰îÿÿÿÀGWà¥à°€þÍðŠ à‰îÿÿÿð¹õà¥àú €´¼ðŠ à‰¶îÿÿÿÀGWà¥à°€þÍðŠ à‰îÿÿÿÀGWà¥àú €´¼ðŠ à‰5îÿÿÿÀGWà¥à°€þÍðŠ à‰ îÿÿÿÀGWà¥àú €´¼ðŠ à‰RîÿÿÿÀGWà¥à°€þÍðŠ à‰ îÿÿÿÀGWà¥àú €´¼ðŠ à‰)ðÿÿÿÀGWà¥à®ÝðŠ à‰îÿÿÿÀGWà¥à°€þÍðŠ à‰ 0îÿÿÿÀGWà¥àú €´¼ðŠ à‰àîÿÿÿÀGWà¥à°€þÍðŠ à‰îÿÿÿÀGWà¥àú €´¼ðŠ à‰vðÿÿÿð¹õà¥à®ÝðŠ à‰îÿÿÿÀGWà¥à°€þÍðŠ à‰`bðÿÿÿÀGWà¥à®ÝðŠ à‰ðÿÿÿÀGWà¥à®ÝðŠ à‰îÿÿÿÀGWà¥à°€þÍðŠ à‰*îÿÿÿÀGWà¥àú €´¼ðŠ à‰@ðÿÿÿÀGWà¥à®ÝðŠ à‰îÿÿÿÀGWà¥à°€þÍðŠ à‰ îÿÿÿÀGWà¥àú €´¼ðŠ à‰CðÿÿÿÀGWà¥à®ÝðŠ à‰îÿÿÿÀGWà¥à°€þÍðŠ à‰=1(ÐðÿÿÿÀGWà¥à®ÝðŠ à‰îÿÿÿð¹õà¥à°€þÍðŠ à‰QðÿÿÿÀGWà¥à®ÝðŠ à‰$U]þÿÿ d?ppTableElemsAlloc;Syntax10.Scn.FntSyntax14.Scn.FntUi/columns "-l"/table 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) kµ ž#Éýÿÿ ]Uàì#vSyntax14.Scn.FntSyntax10.Scn.FntåÿÿÿÀGWà¥ParcElemsAllocà®ÝðŠ à‰ ’.À¸ÿàÃÙ«Â/columns "-lll"/table 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 @ò›ýÿÿ ]U£.lSyntax10.Scn.FntèÿÿÿÀGWà¥ParcElemsAllocà®ÝðŠ à‰ ÁÈ€ä¯Syntax14.Scn.Fntùú/columns "-lll"/table 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 ðÿÿÿð¹õॠÆê°š Ðíÿÿÿò+€ý;Syntax10.Scn.Fnt/Syntax12.Scn.Fnt–Å/nohead V /left 30 /top 10 /column LLLL /table 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 Syntax10i.Scn.FntðÿÿÿÀGWà¥à®ÝðŠ à‰êâ 1!^H":t<Ò)  Linux-Oberon User Guide (origin: J. Templ /SPARC architecture, adapted: M. Dƒtwyler, M. Sperisen) Abstract  Linux-Oberon is an implementation of Oberon for Intel based Linux Systems. It covers both the programming language Oberon including the Oberon-2 language extensions and the Oberon System closely resembling the original implementation on Ceres. Hence, this report describes only the differences between Linux-Oberon and the Ceres implementation (Ceres-Oberon) from a user's point of view. Contents  1. Introduction 2. Installation 3. Differences to Ceres-Oberon 4. Data Representation and Alignment 5. Low-level Facilities References 1. Introduction The programming language Oberon [1, 2] evolved from a project with the goal of developing a portable operating system (also named Oberon) for personal workstations [3, 4, 5]. The original Oberon implementation on Ceres workstations proved to be useful for doing many kinds of personal computing including program development, document preparation, and teaching programming. Oberon is available on a wide range of other machines, based on MC68020, MIPS, RS/6000, HP, and Intel 80386 processors. This report focuses on the version for Intel Based Linux. Linux-Oberon has been designed to be as (Ceres-)Oberon-like as possible. Linux-Oberon runs as a single Unix-process and requires X-Windows, a three-button mouse and a keyboard. It makes no sense to run Oberon via a serial terminal or via remote login. However, in principle it is possible to provide for special Oberon subsets running on terminals just to use the language, or to provide for an Oberon version based on a client server model. As the Oberon system relies on dynamic loading of modules (without pre-linking), which was not supported by Linux, it has been necessary to use special object files and a special loader. This allows for arbitrary extensibility of Oberon programs and for low overhead in the edit-compile-execute cycle, typically requiring only two mouse clicks and almost no time. 2. Installation Linux-Oberon may be installed on all Intel based Linux systems. To install Linux-Oberon you just have to copy all files of the distribution medium into a directory. This directory is intended to be the public Oberon library. The preferred name for it is /usr/local/Oberon and it is a good idea to make this library read only. File naming conventions: Files ending with ".tgz" are compressed archives and may be uncompressed by the command tar zxvf file.tgz. The Oberon environment may be entered by executing the command oberon. The calling syntax of the oberon command is: oberon [-h heapSize] [-f defaultFont] [-x Mod Proc] options: -h heapSize set heap size to specified number of bytes. If not specified, 4 MB are used for the Oberon heap. -f defaultFont set default font to specified font name. If not specified, Syntax10.Scn.Fnt is taken as default font. -x Mod Proc execute command Mod.Proc. If not specified, Oberon.Loop is executed. New files are always allocated in the current directory, files used internally by Oberon the /tmp directory. Internal files are named .tmp.pid.nr, where pid is a process id and nr is a unique number within this process. Make sure, that you have read and write permission in the current directory. The search path for existing files is specified by the environment variable OBERON. The default setting for OBERON is .:/usr/local/Oberon. This means, if the environment variable OBERON doesn't exist, files are first searched in the current directory and second in the public Oberon library. Following Unix conventions, colons are used as path name separators. Environment variables may be set under the C-shell by the command setenv (e.g. setenv OBERON .:MyLib:/usr/local/Oberon). 3. Differences to Ceres-Oberon Linux-Oberon differs in some details from Ceres-Oberon. These differences are due to the underlying hard- and software. However, Oberon programs that do not use low-level features are fully portable. There are no differences in the implemented language. Module System provides additional commands for the integration of Oberon into Unix. Module Display handles screen maps and patterns differently. Module Unix provides a low level interface to the underlying operating system. Module Input emulates some keys that are not available on PC keyboards. Module Files provides an additional procedure to change the working directory. Module Oberon returns the time in milliseconds instead of 1/300 seconds. Module Printer generates PostScript output. Module Miscellaneous does not provide commands specific to Ceres-Oberon. The Net, and ColorSystem tool packages are not implemented (use corresponding Unix commands). The modules Display1 and Files1 provide additional display and file operations. System Suspend Stop the Oberon process and preserve its state. When working under SunView, Oberon may be reentered by clicking at the oberon icon, otherwise by executing a foreground command (fg). Quit Kill the Oberon process and remove temporary files. Execute command | ^ Execute an arbitrary (non-interactive) bourne-shell command and display its output in a text viewer. The command is terminated by "end of line". If System.Execute is followed by a "^", the most recent text selection is executed, where multiple lines are separated by blank characters and the command is terminated by "end of selection". ChangeDirectory newdir | ^ Change the working directory to newdir. Display NewPattern (image: ARRAY OF SET; W, H: INTEGER): Pattern; (has been moved into module Display1) Return a descriptor to a new pattern initialized with image. Each line of the image is expected to be stored as a sequence of sets. The bottom left bit is defined by bit 0 of image[0]. Map (X, Y: INTEGER): LONGINT; Return the address of screen map at X, Y. Procedures drawing only on the optional color screen are not implemented. Unix Module Unix provides an Oberon interface for all Linux system calls and defines all data types and error numbers used in these calls. The procedure Unix.Errno() may be used to check for success and to examine the error number. Note that Unix procedures trap directly into the Linux kernel. Therefore, the procedural interface is different from the corresponding C-library functions. Module Unix is implemented by dynamically linking and calling the corresponding C-library functions. Currently, not all of the Linux system calls are implemented. It is however, fairly easy to access additional system calls (additional note: not yet fully supported due to not existing C-interface to Linux dynamic loader), e.g. VAR waitpid: PROCEDURE (pid, statusp, options: LONGINT): LONGINT; BEGIN Kernel.dlsym(Kernel.libc, "waitpid", SYSTEM.VAL(LONGINT, waitpid)); res := waitpid(42, 0, 64); IF res = -1 THEN Out.String("errno = "); Out.Int(Unix.Errno(), 1); Out.Ln; ELSE ...ok END  Files ChangeDirectory (path: ARRAY OF CHAR; VAR res: INTEGER); Change the working directory. A zero result indicates success. Oberon Time (): LONGINT; Return the time since start of the Oberon system in milliseconds. Printer Module Printer generates a (temporary) PostScript file named Oberon.Printfile.ps and sends it to a printer using the Unix command lpr. A header file Oberon.Header.ps is always included at the beginning of Oberon.Printfile.ps. The printer name none specifies that only the file Oberon.Printfile.ps should be generated. The header file may be used to specify the mapping from Oberon to PostScript fonts. It may also be used to scale output such that it fits on the actual paper size (e.g. for US-letter). Backup Module Backup provides for an additional command Eject to eject the floppy disk. (not yet implemented) 4. Data Representation and Alignment The following table shows the internal representation of data types in Linux-Oberon:  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. 5. Low-level Facilities 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:  The function SIZE remained in the language as defined in [1]. SIZE(T) returns the number of bytes reqired 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:  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.  Numbering of 80x86 registers  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 { "," 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. References 1. N. Wirth. The programming language Oberon. Software-Practice and Experience, 18 , 7 (July 1988) 2. N. Wirth. From Modula to Oberon & The Programming Language Oberon Report 143, ETH Zurich, 1990. 3. N. Wirth, J. Gutknecht. The Oberon System. Software - Practice and Experience, 19, 9 (Sept. 1989) 4. J. Gutknecht. The Oberon Guide Report 138, ETH Zurich, 1990. 5. M. Reiser The Oberon System, User Guide and Programmer's Manual Addison-Wesley, 1991 File: LinuxOberon.Text / M. Dƒtwyler, M. Sperisen / 12.7.94