Chapter 3, Writing RCOS Programs

I love being a writer. What I can't stand is the paper work.

-- Peter De Vries

Introduction

The programs that an operating system executes must be written using the machine language and format that is specific to the hardware platform the operating system runs on and the operating system itself. The "machine language" that RCOS uses is called P-Code (pseudo code). Under RCOS the P-code instructions are "executed" by an interpreter built into RCOS (the file PCI.CPP). The interpreter simulates the actions of a normal CPU.

No programmer writes programs directly in the machine language of their platform. Instead they write programs in a higher level language (assembly language, Pascal, C, Ada, Prolog etc) and then use a compiler to translate the program into machine language. You should find included with RCOS a compiler called pll2. This compiler "translates" a language called Pascal Like Language 2, which (surprise, surprise) is very similar to Pascal, into p-code.

This chapter outlines the process and details of writing a PLL/2 program, compiling it and then running it under RCOS. The next chapter will introduce you to writing PLL/2 programs that use the special features of PLL/2, including shared memory and semaphores.

How to Produce a RCOS Program

Figure 3.1 outlines the process for creating your own executable RCOS programs.

Use the operator console commands mentioned in the previous chapter.

Figure 3.1.

Steps to produce and RCOS Program.

PLL/2

The Origins of PLL/2

PLL/2 is an implementation of a concept first published in Byte Magazine, in the late 1970s, for a "tiny" Pascal language implementation. RCOS is distributed with a compiler that translates programs written using a Pascal like syntax into p-code that RCOS can execute. The RCOS compiler is written in Borland Turbo Pascal (the original was in North Star Basic).

Standard Features of PLL/2

For the purposes of this document it is assumed that you are already familiar with the Pascal language. If you are not it is suggested that you become so before progressing much further.

PLL/2 is a sub-set of Pascal and uses a similar syntax and structure with some notable exceptions. Figure 3.2 contains a list of reserved words and Figure 3.3 lists some of the special symbols.

If a language feature does not appear in either of these figures then it is not supported. Note, for instance, there is no SET type, or set operators. The exceptions to standard Pascal are detailed in the next section.

AND		ARRAY	BEGIN
CASE		CONST	DIV	
DO		DOWNTO	ELSE	
END		FILE	FOR	
FUNCTION	IF	INTEGER
MEM		MOD	NOT		
OF		OR	PROCEDURE	
PROGRAM		READ	REPEAT
SHL		SHR	THEN		
TO		TYPE	UNTIL 
VAR		WHILE	WRITE
WRITELN		XOR

Figure 3.2.

PLL/2 Reserved Words.

+   -   *   /   =   <   >   [   ]   .   ,   (  )    ;   {  }   #   %
  <=  >=  :=  <>

Figure 3.3.

Special Characters.

Differences from Standard and Turbo Pascal

By virtue of its age and origin, PLL/2 inherits some departures from standard Pascal syntax, which is one of the reasons it's not called Pascal. These are outlined below.

Program Statement

PLL/2 conforms to the original Pascal syntax that requires that programs intending to perform input to output declare their intentions as an argument list to the program name. This allows the compiler to generate a resource requirement list for the object code header, giving RCOS the option to take some of the "classic" deadlock avoidance measures.

Data Types

PLL/2 supports only type INTEGER. Characters are treated as a special case of the integer type. For further details, refer to the sections on READ, WRITE and WRITELN.

Arrays

In PLL/2, all arrays are assumed to index from zero (just like C, there's no place like home). There is no support for explicit array subscripting, so attempts to define something like the line below will fail. Use a single integer to indicate the number of elements required in the array.

VAR
  Foo: ARRAY [1..MAX_LEN] OF INTEGER;	{ ERROR! Range not supported }
  Bar: ARRAY [MAX_LEN] OF INTEGER;	{ Correct! }

Read, Write and Writeln

Unlike Pascal, PLL/2 provides no support for formatted numeric output. In addition since since characters are treated as a "special case" of integers how does the system know when to display an integer as a character or as an integer. PLL/2 uses an unusual convention where the variable name can have a suffix that specifies the way a variable is to be interpreted, for both input and output Table 3.1. summarises the suffixes and their use

 Suffix    Purpose                
    #      decimal numbers        
    @      File handle            
    %      hexadecimal numbers    
  none     ascii characters       

Table 3.1.

Suffixes for Input/Output.

For example,

The code fragment

val := 65;

Writeln(val, ' ', val#, ' ', val%);

produces the following output

A 65 0041

Later on in this chapter is an example program that makes use of variable suffixes.

Extensions to Standard and Turbo Pascal

PLL/2 has a built-in function, SYSTEM, that allows programs to access special features provided by RCOS. The first parameter to the function is an identifier, valid identifiers are listed in the PCI.HPP file (PCI.HPP is the header file for the P-Code interpreter). This identifier informs RCOS which special feature the program wishes to access. The feature is accessed through what is basically an RCOS system call.

The major use you will have for the SYSTEM function is in programs using semaphores and shared memory (examine semtx9.pll and sher1.pll in the RCOS directory). Chapter 4 explains in more detail writing programs that make use of RCOS's IPC primitives.

The PLL/2 Compiler

The operation of the PLL/2 compiler is extremely simple. As supplied, PLL/2 runs under MS or PC-DOS (version 2.0, or later). It is command line driven, expecting the name of a suitable source code file as a single argument. The full source code file name, including extension and path if required, must be supplied. No assumptions are made regarding the extension.

For example,

C:>PLL2 PRIMES.PLL

loads the compiler and compiles the file "primes.pll" (since there are minor syntactic differences from Pascal, changing the extension is probably a good idea). Any errors encountered during the compilation are reported to the console in the form:

ERROR xx (yy): <text>

Where xx is an internal error reference code, yy is the offending line number in the source code file and <text> is a description of the error encountered. PLL/2 performs no error recovery, hence any messages generated after the first may be a consequence of the first. After a set number of errors, the compiler will abort.

If any errors are encountered during execution, no object code is produced. An error-free run will produce a file with the same primary name as the source code, but with the extension PCD. This is written to the same directory as the source code file. If a file of this name already exists, it is over-written.

The Stand-Alone P-Code Interpreter

The current p-code interpreter does not support some of the recently added PLL/2 extensions including file I/O, semaphores and shared memory.

The prime reason for the existence if PLL/2 is to provide executable programs for RCOS. To make the debugging of PLL/2 programs easier a DOS mode p-code interpreter and debugger is provided with the release. Written in standard ANSI C, it was used during the development of RCOS programs to examine and test the code being produced by the compiler and allows PLL/2 programs to be run under DOS.

To execute, type:

C:>PCODE filename [-D|M]

Where filename is the name of a p-code program file and an optional -M switch, if used, loads the interpreter in debug mode. The -D switch produces a disassembly of all the p-codes in the names file to standard output, allowing it to be easily re-directed to a file. The default, with no switch, simply executes the PLL/2 program and exits to DOS. Execution with no argument gives a usage message.

P-Code Interpreter V1.12

Commands:

G: Go (resume)

S: Single Step

R: Reset

B: Set break-point

C: Clear all break-points

Y: Display break-points

X: Examine status

K: Show stack

L: List p-codes

T: Trace back

E: Examine memory

U: Backup PC

N: Increment PC

Q: Quit program

?: Display help (this!)

Figure 3.4.

P-code Debug Commands

It is not intended that this program be used for any other purpose than p-code validation during development, so this manual will not go into any details of the debug mode. If you need to run the debugger (perhaps to test modifications you may have made to the compiler, or just for curiosity), typing a question mark at any time - when in debug mode - will display a command summary. This summary is shown in Figure 1. If in any doubt regarding the admittedly cryptic debugger output, refer to the source code file.

An Example PLL/2 Program

The following is an example of writing and compiling a PLL/2 program using the supplied compiler.

Aim

Write a program that displays

1 in hex is 1

for all the numbers between 1 and 500.

The Code

The FIRST attempt at writing a program to fulfil this aim is listed below. THIS CODE IS INCORRECT AND WILL GENERATE ERRORS WHEN COMPILED.

PROGRAM TEST (OUTPUT);

VAR
  I : INTEGER;

BEGIN
  FOR i := 1 TO 500 DO
  BEGIN
    Write( I#, ' in hex is ' );
    Writeln( I%);
  END;
END.

The program is created as a normal MS-DOS based text file and is save under the name ftest1b.pll.

Compiling and Debugging

Over the page is an attempt to compile the program. You will notice there are a number of error messages. These errors are caused by the line

Writeln( I%);

The reason is that the PLL/2 language

will not allow a semi-colon to precede a line with an END unless that END is the final one for the program.

Removing the ; at the end of the above line and recompiling the program will result in a compile without errors.

C:\SUBJECTS\84349\RCOS\RCOS>pll2 test.pll

------------------------------------
P-Code PASCAL Compiler  Version 2.00
for OS Simulator.  Ron Chernich 1992
------------------------------------

* Error 15 (12): Incorrect symbol (maybe ";" on previous line?)
* Error 15 (15): Incorrect symbol (maybe ";" on previous line?)
* Error 13 (15): ";" or END expected

*** Maximum errors exceded - aborting ***

Executing the Program

After successfully compiling the (modified) program FTEST1B.PLL perform a directory listing of the directory the program was in. You should observe a file called ftest1b.pcd. This is the RCOS executable program and can be executed two ways

  • using the p-code interpreter program, or
  • using RCOS itself.

    Conclusions

    This chapter has introduced you to the method used to create RCOS executable programs including introducing you to the PLL/2 programming language. In doing this you have been shown how that language differs from standard Pascal and how it is possible to make use of the special RCOS features shared memory and semaphores.

    You have also been introduced to the PLL/2 compiler and interpreter/debugger distributed with RCOS.