New language extension: BYTE data type

Topics related to the use of Oberon language features
Locked
cfbsoftware
Site Admin
Posts: 493
Joined: Fri Dec 31, 2010 12:30 pm
Contact:

New language extension: BYTE data type

Post by cfbsoftware » Fri Jul 27, 2012 1:30 pm

Starting with release 4.4 of Astrobe the data type BYTE is included as an Oberon language extension to replace the existing extension SYSTEM.BYTE. The BYTE type is primarily intended to be used when transferring 8- and 16-bit data to and from peripheral devices. Although BYTE variables could be used wherever an INTEGER variable is allowed (except where noted here) INTEGERs should always be used unless there is a compelling reason to do otherwise.

BYTE is an unsigned INTEGER with a minimum value of 0 and a maximum value of 255. No overflow checking is performed on BYTE variables at runtime.

BYTE variables can be assigned to INTEGER variables. Constants in the range 0..255 can be assigned to BYTE variables. Attempts to assign a constant outside this range will result in the compile-time error: incompatible assignment.

An example of a safe way of typecasting an INTEGER value to a BYTE is as follows:

Code: Select all

PROCEDURE* IntToByte(i: INTEGER): BYTE;
BEGIN
  ASSERT(LSR(i, 8) = 0);
  RETURN SYSTEM.VAL(BYTE, i)
END IntToByte;


If a formal parameter to a procedure is defined as ARRAY OF BYTE the actual parameter may be of any data type. The parameter can then be accessed byte-by-byte in the body of the procedure e.g.

Code: Select all

VAR
  data: INTEGER;
  b1, b2, b3, b4: BYTE;
  
PROCEDURE WordToBytes(w: ARRAY OF BYTE; VAR b1, b2, b3, b4: BYTE);
BEGIN
  ASSERT(LEN(w) = 4, 20);
  b1 := w[0];
  b2 := w[1];
  ...
  ...
  
WordToBytes(data, b1, b2, b3, b4);
If a parameter is truly an array of bytes with a fixed size, it should be defined as a TYPE to prevent arbitrary data types from being passed to it e.g.

Code: Select all

TYPE
  Buffer = ARRAY 256 OF BYTE;
  
PROCEDURE SendData(bytes: Buffer);

cfbsoftware
Site Admin
Posts: 493
Joined: Fri Dec 31, 2010 12:30 pm
Contact:

Re: New language extension: BYTE data type

Post by cfbsoftware » Sun Sep 29, 2013 12:54 am

Note that SYSTEM.PUT generates either the STRB instruction to store an 8-bit BYTE value or the STR instruction to store a 32-bit word value depending on whether the parameter passed is a byte-sized (e.g. BYTE, CHAR etc.) or word-sized (e.g. INTEGER, SET etc).

Hence, when using SYSTEM.PUT to store a constant value in the range 0..255 you should take care to use whichever of the following you prefer to make it clear whether a byte or integer is being transferred, as required:

Code: Select all

   (* BYTE transfers *)
   VAR
     addr: INTEGER;
     b: BYTE;
     ...
   BEGIN
     SYSTEM.PUT(addr, 0X);
     SYSTEM.PUT(addr, CHR(0));
     b := 0;
     SYSTEM.PUT(addr, b);
     ...

Code: Select all

   (* INTEGER transfers *)
   VAR
     i, addr: INTEGER;
        ...
   BEGIN
     SYSTEM.PUT(addr, ORD(0));
     i := 0;
     SYSTEM.PUT(addr, i);
     ...

Alexander Shiryaev
Posts: 17
Joined: Mon Apr 04, 2011 7:20 pm
Location: Russia
Contact:

Re: New language extension: BYTE data type

Post by Alexander Shiryaev » Mon Sep 30, 2013 7:31 am

cfbsoftware wrote:

Code: Select all

(* INTEGER transfers *)
...
SYSTEM.PUT(addr, ORD(0))
...
May be

Code: Select all

SYSTEM.PUT(addr, 0)
or

Code: Select all

SYSTEM.PUT(addr, ORD(0X))
?

cfbsoftware
Site Admin
Posts: 493
Joined: Fri Dec 31, 2010 12:30 pm
Contact:

Re: New language extension: BYTE data type

Post by cfbsoftware » Mon Sep 30, 2013 8:23 am

I deliberately omitted the case where the programmer does not explicitly specify what type the constant is i.e.

Code: Select all

SYSTEM.PUT(addr, 0)
It is not obvious / could easily be forgotten that this will result in a byte-transfer only. This can lead to obscure errors e.g.

Code: Select all

SYSTEM.PUT(LPC.VICVectAddr, 0)
An alternative solution may be for us to introduce two new functions PUTWORD and PUTBYTE.

Alexander Shiryaev
Posts: 17
Joined: Mon Apr 04, 2011 7:20 pm
Location: Russia
Contact:

Re: New language extension: BYTE data type

Post by Alexander Shiryaev » Mon Sep 30, 2013 9:15 am

Introduction of new data type leads to problems, which not exist before.

If you want to introduce integer BYTE type, may be better to keep INTEGER (word addressing) as default integer data type?

Then, SYSTEM.PUT(addr, any integer constant) should generate STR, not STRB instruction.

In any case, ORD(0) syntax is strange.

cfbsoftware
Site Admin
Posts: 493
Joined: Fri Dec 31, 2010 12:30 pm
Contact:

Re: New language extension: BYTE data type

Post by cfbsoftware » Sat Nov 30, 2013 6:05 am

We have now decided that when we release the version of Astrobe which conforms to Oberon Rev 1.10.2013 the constants 0 .. 255 will be compatible with BYTE and INTEGER variables in assignments, but will be treated as INTEGERs when their type cannot be determined by the context (e.g. as parameters to SYSTEM.PUT).

The following example shows when SYSTEM.PUT and SYSTEM.GET will generate byte-sized transfer instructions and when they will generate word-sized transfer jnstructions. Note that it will not be necessary to use ORD(0).

Code: Select all

MODULE PutGet;

IMPORT SYSTEM;

PROCEDURE* P;
VAR
  adr: INTEGER;
  (* Word-sized variables *)
  integer: INTEGER;
  real: REAL;
  set: SET;
  pointer: 
    POINTER TO RECORD 
      integer: INTEGER 
    END;
  (* Byte-sized variables *)
  boolean: BOOLEAN;
  byte: BYTE;
  char: CHAR;
BEGIN
  (* Word transfers *)
  SYSTEM.PUT(adr, integer);
  SYSTEM.PUT(adr, real);
  SYSTEM.PUT(adr, set);
  SYSTEM.PUT(adr, pointer);
  SYSTEM.GET(adr, integer);
  SYSTEM.GET(adr, real);
  SYSTEM.GET(adr, set);
  SYSTEM.GET(adr, pointer);
  SYSTEM.PUT(adr, 0); 
  SYSTEM.PUT(adr, 255); 
  SYSTEM.PUT(adr, 256); 
  SYSTEM.PUT(adr, 0FFH); 
  SYSTEM.PUT(adr, 07FFFFFFFH); 
  SYSTEM.PUT(adr, ORD(boolean));
  SYSTEM.PUT(adr, ORD(byte));
  SYSTEM.PUT(adr, ORD(0FFX));
  SYSTEM.PUT(adr, ORD(char));
  SYSTEM.PUT(adr, ORD("a"));
  SYSTEM.PUT(adr, 0.0);
  SYSTEM.PUT(adr, 3.142);
  SYSTEM.PUT(adr, {}); 
  SYSTEM.PUT(adr, {0..31}); 
  SYSTEM.PUT(adr, NIL); 
  
  (* Byte transfers *)
  SYSTEM.PUT(adr, boolean);
  SYSTEM.GET(adr, boolean);
  SYSTEM.PUT(adr, byte);
  SYSTEM.GET(adr, byte);
  SYSTEM.PUT(adr, char);
  SYSTEM.GET(adr, char);
  SYSTEM.PUT(adr, TRUE);
  SYSTEM.PUT(adr, SYSTEM.VAL(BYTE, 0));
  SYSTEM.PUT(adr, 0X);
  SYSTEM.PUT(adr, 0FFX);
  SYSTEM.PUT(adr, "x");
  SYSTEM.PUT(adr, CHR(0));
  SYSTEM.PUT(adr, CHR(integer));
END P;

END PutGet.
  

Alexander Shiryaev
Posts: 17
Joined: Mon Apr 04, 2011 7:20 pm
Location: Russia
Contact:

Re: New language extension: BYTE data type

Post by Alexander Shiryaev » Sat Nov 30, 2013 8:51 pm

It's good

Locked