,ll 6.6
,cs 10
,pl 66
,lm 0.2,0.5
,pn 22
,ju
,hd
,ce
OmegaSoft 6809 Cross Pascal Language Handbook (V1.0)
,,
,ft

,ce 1
4-##
,,
,ce
OmegaSoft 6809 Cross Pascal Language Handbook (V1.0)
,ce
TYPE DECLARATIONS

The mantissa is expressed as a 24 bit unsigned normalized fractional value. The exponent is expressed as a two's complement 7 bit value having a range of -64 to 63. The most significant bit is the sign of the mantissa (0 = positive, 1 = negative), for a total of 32 bits. The binary point is assumed to be to the left of the most significant mantissa bit (23). Bit 23 must be equal to 1 (normalized) except for zero (all bits = 0).

real-type = real
real-constant = signed-real | real-constant-identifier

STRUCTURED TYPES

The structured types include strings, arrays, records, sets, and devices and files. The reserved word "packed" may precede any of these type declarations, but has no effect in OmegaSoft Pascal.

STRINGS

String types are most often used to represent strings of ascii characters. A unique feature of OmegaSoft Pascal is that each character in a string may be any 8 bit value, there is no special value used as a terminator. This implies that strings can be used for any variable length data up to 126 bytes in length.

String types are declared by following the identifier "string" by an integer number in brackets. The integer number defines the string's "static length", or longest possible length. Optionally, this integer in brackets can be left off, and the static length will be assumed to 80.

A string consists of a 1 byte dynamic length "n" in the range of 0 .. 126 followed by "n" bytes of characters. String variables occupy the declared length of the string plus one byte. The current dynamic length is at the lowest address, followed by the actual data. If the current string is shorter than the declared length, then any bytes following the string are garbage.

When a string value is used in expressions or returned from a function they occupy the current dynamic length of the string plus one byte on the stack. Even if the string is declared as 100 bytes, the string 'ABC' will occupy only 4 bytes on the stack. The dynamic length will be at the lowest address on the stack.

When a string value is passed as a parameter by value then the string will occupy the declared length of the parameter declaration plus one byte on the stack. The dynamic length will be at the lowest address on the stack. As an example, for the procedure declaration :

procedure a (b : string [40]) ;

If the string 'ABC' were to be passed to this procedure it would occupy 41 bytes on the stack. The lowest addressed byte would have the dynamic length (3), the next three addresses would have A, B, and C, and the next 37 bytes would be garbage. This is done so that the called procedure can access the parameter at a fixed offset from the stack mark, regardless of the size of the parameter.
,pg
,ce
TYPE DECLARATIONS

String constants consist of zero or more (up to 126) characters within single quotes. Note that in a string-constant if it is necessary to represent the single quote (') it must be written twice (''). String constants can also contain imbedded non printable characters anywhere in the string constant. This is accomplished by allowing multiple sections of string and character constants to be automatically concatenated together. Each character constant must be preceded by a "#" symbol and there must be no spaces (or end of line) between sections. As examples of valid string constants :

'this is a simple string constant'
'this constant contains a single quote '' in it'
'null terminated string'#0
'backspace, space, backspace is '#8' '#8
'Ring that bell!'#7#7#7

string-type = string [ [ unsigned-integer ] ]
simple-string-constant = ' { character } ' |
                          string-constant-identifier
string-constant = {simple-string-constant | # (char-constant |
                   integer-constant | hex-constant) }

ARRAYS

An array is a group of variables all of the same type. Each variable in the array is called an element of the array and they are accessed by using the array identifier name and an index (or subscript). The index of an array can be any ordinal type except full range integer, hex, longinteger or longhex. The element of the array can be any type.

The array is defined by following the reserved word "array" by the index declaration in brackets, in most cases this is a subrange. After the index declaration the reserved word "of" is used, followed by the element type declaration.

An array variable must not occupy larger than  32K bytes of memory. This byte count is determined by multiplying the size of the element times the range of the index, for instance :

array [0..31] of string [15]      occupies 32 * 16 = 512 bytes.

The above array variable would occupy 512 bytes in memory, either as a variable, or on the stack if passed as a parameter by value. The above array could not be returned from a function, but if the size of an array is less than 127 bytes, it can be a function return value. Two arrays are compatible if their size is equal.

If the element of an array is another array, then a multidimensional array is created. In OmegaSoft Pascal there is no limit on the number of dimensions possible, as long as the maximum size limit for the outer array is honored. There is a shorthand method of specifying multidimensional arrays :

array [1..5] of array ['A'..'C'] of integer ; is equivalent to :

array [1..5, 'A'..'C'] of integer
,pg
,ce
TYPE DECLARATIONS

Multidimensional arrays are stored with the last index changing most rapidly. In the above array, the elements would be stored in memory as :

1-A 1-B 1-C 2-A 2-B 2-C 3-A 3-B 3-C 4-A 4-B 4-C 5-A 5-B 5-C

In ISO standard Pascal there is a concept called a character string variable defined as :

packed array [1..n] of char

This variable can be used as a sort of "string" in that it can accept string constants and be written out to a text file. The catch is that ALL of the characters are valid at all times, so this is not as good as the OmegaSoft Pascal string type. Note that if you must use this form that when assigning a string constant to this array that the length of the constant must match the declared length "n" or there will be garbage in the variable that will be considered valid.

OmegaSoft Pascal supports this form of string by allowing it to be written to a text file, and by making arrays of less than 127 bytes compatible with string constants and string variables.

index-type = ordinal-type
array-type = [packed] array [ index-type {, index-type} ]
             of type

 
       packed     array    [      index-type       ]    of

 
                                       ,              type


RECORDS

Records are used to organize different data types into a new data type. Records have a fixed number of elements called fields. Fields consist of a fixed part (i.e. fixed size and definition) and a variant part (variable size and definition).

Each field in the fixed part of the record is allocated space immediately following the previous field. Each variant part starts allocation at the same location, therefore each variant uses the same space in a record. The tag field of the variant part is allocated space (if it is a variable definition) before the variants are allocated space. As an example of the allocation used, in the record :

alloc = record
          a, b : hex ;
          c : real ;
          d : string [4] ;
          case e : integer of
            0 : (f : real) ;
            1 : (g : string [4]) ;
            2 : (h : record
                       i,j : char
                     end)
        end ;
,ce
TYPE DECLARATIONS

the fields use the following memory locations (relative to the start of the record) :

a : 0 - 1               b : 2 - 3               c : 4 - 7
d : 8 - 12              e : 13 - 14             f : 15 - 18
g : 15 - 19           h.i : 15                h.j : 16 

The tag type must be an ordinal type and the tag constants must be the same type. The particular tag constants have no meaning other than signaling the start of a new variant. The variant part must be defined after the fixed part, but variant parts can  nested. Variable identifiers must be unique within a record only. A field in a record is referenced by the record name followed by the field name.

The size of a record is the size of the fixed part plus the size of largest variant part, either as a variable, or on the stack if passed as a parameter by value. A record can be returned from a function if its size is less than 127 bytes. No record can exceed 32K bytes.

Two records are compatible if their sizes are equal.

record-type = [ packed ] record [field-list [;]] end
field-list = [ fixed-part ] [ ; variant-part ] | variant-part
fixed-part = record-section { ; record-section }
record-section = identifier {, identifier } : type
variant-part = case variant-selector of variant { ; variant }
variant-selector = [tag-field :] ordinal-type
tag-field = identifier
variant = constant {, constant} : ( [field-list [;]] )

Record-type :
 
     packed      record         field list       ;      end

 
Field list :
 
      fixed part       ;       variant part   

 
Fixed part :
 
         field identifier        :        type
                
                 ,              
                                 ;


Variant part :
 
     case     identifier     :        type       of
 
 
       constant       :     (     field list      ;      )
    
          ,
                             ;
,pg
,ce
TYPE DECLARATIONS

SETS

Sets are a collection of ordinal data items. Each set can have up to 1008 elements with ordinal values from 0 to 1007.

Sets are defined by following the reserved words "set" "of" with the base type of the set. The maximum ordinal value that the base type can have determines the amount of memory allocated for the set. The size is = maximum ordinal value div 8 + 2.

Sets are useful for collecting a series of attributes together, and to be able to insert and remove attributes without affecting the other attributes. For instance, in an assembler you could have an enumerated type :

stat = (declared,forward,encountered,absolute,relative) ;

and a set variable :

status : set of stat ;

You would then be able to set in the encountered attribute by using :

status := status + [encountered] ;

without affecting any of the other attributes, likewise you could remove the forward attribute by :

status := status - [forward] ;

One of the most common use of sets is in characters sets. For instance to check if a character is a letter, digit, or an "_" you could use a check like :

if upshift (ch) in ['A'..'Z','0'..'9','_'] then .....

which is much nicer than the multiple range checking alternative.

A set physically consists of a dynamic set length "n" (first byte) in the range of 0 .. 126 followed by "n" bytes. The lowest (ordinal value) element in the set is the least significant bit in the last byte of the set. The last byte contains elements 0 through 7, the second to the last byte contains elements 8 through 15 (element 8 is LSB), etc. If the current set is shorter than the amount allocated for the set, then any bytes following the "n" bytes are garbage.

When a set value is used in expressions or returned from a function they occupy the current dynamic length of the set plus one byte on the stack. If the set is declared as requiring 100 bytes, the set [4,12,19] will occupy only 4 bytes on the stack. The dynamic length will be at the lowest address on the stack.

Any set is compatible with any other set as long as an assignment is not made to a set variable that would require more memory than allocated to that variable.
,pg
,ce
TYPE DECLARATIONS

When a set value is passed as a parameter by value then the set will occupy the declared length of the parameter declaration plus one byte on the stack. The dynamic length will be at the lowest address on the stack. As an example, for the procedure declaration :

procedure a (b : set of 0..250) ;

If the set [4,12,19] were to be passed to this procedure it would occupy 33 bytes on the stack. The lowest addressed byte would have the dynamic length (3), the next three addresses would have $08,$10,$10, and the next 29 bytes would be garbage. This is done so that the called procedure can access the parameter at a fixed offset from the stack mark, regardless of the size of the parameter.

set-type = set of ordinal-type
set-constant = see chapter 5 under set expressions

DEVICES AND FILES

A device is a sequence of data items, all with the same type, called components or elements of the device. The elements of a device can be any type, except for another device or any structure containing a device. The element of a device cannot exceed 32K bytes in size. Devices are the entity that represent I/O devices in a system.

A file is a special type of device normally associated with a random access disk, that have names that go with a specific group of data on the device. Procedures are included in Pascal to access these groups of data by their "file name".
 
A device consists of zero or more elements, only one of which can be accessed at any particular moment. The element is stored in a series of one or more locations in the device descriptor called the element buffer. This serves as a "window" through which the Pascal program can read or write to a device. The number of elements is not fixed and can vary up to the amount allowed for the particular device. 

For every device declared there is automatically another variable which is called the buffer variable. This buffer variable points to the element buffer allowing the data to be transferred in and out of the device through the "window". 

Devices are automatically initialized upon entering the block in which they are defined. For the standard devices (Input, Output, Keyboard, and Auxout) this means upon entering the main program block. For all but the standard devices, the device should be closed when no further accesses will be done. 

All devices are assumed to be system level, they don't magically disappear when a block is exited. If you want a temporary file, delete it when you are done with it.

