ABSOLUTE: bug report, plus some suggestions

Post your requests and ideas on the future development of mikroPascal.
Post Reply
Author
Message
Ric
Posts: 44
Joined: 01 Mar 2007 10:35
Location: Italy

ABSOLUTE: bug report, plus some suggestions

#1 Post by Ric » 05 Mar 2007 16:41

There is more than one way in which the absolute directive could be made a lot more useful.

1. There could be a way to intentionally overlap variables, as it is done in Borland compilers:

Code: Select all

var
  myWord: Word;
  myBytes: array[0..1] of Byte; absolute myWord;
No, wait: it can already be done, can't it? :roll:

Code: Select all

var
  myWord: Word;
  myBytes: array[0..1] of Byte; absolute @myWord; // Notice the @
Oops. This won't compile. :? Apparently, mikroPascal (v6.0.0.2 at the time of writing) does not expect a pointer-type constant (or constant expression) after absolute, but an integer constant which it then treats as an address. In a language as strongly typed as Pascal, this is clearly not as it should be. Besides, a pointer-type constant expression should be something the compiler already knows how to parse, since it compiles pointer assignments without a glitch.


2. Since procedure and function parameters are actually static variables, nothing prevents the compiler from allowing them to be at an absolute address:

Code: Select all

unit Multiplexer;

// This unit manages 64 digital outputs using 12 I/O lines:
// - a 3-to-8 decoder is connected to PORTC<2:0>
// - the decoder outputs, together with (inverted) PORTC<3>,
//   enable 8 8-bit non-inverting latches which drive the actual outputs
// - PORTD acts as a data bus; the state of PORTD lines is latched
//   by selecting an output group via PORTC<2:0> and lowering PORTC<3>

const
  gc_Multiplexer_PortCount = 8;

var
  m_PortImage: array[0..gc_Multiplexer_PortCount - 1] of Byte;
  m_Port     : Byte;
  m_Value    : Byte;

// This is called during initialization
procedure Multiplexer_Initialize;
var
  i: Byte;
begin

  TRISC.0 := 0;
  TRISC.1 := 0;
  TRISC.2 := 0;
  TRISC.3 := 0;
  TRISD   := 0;

  PORTC.3 := 1; // Latch enable, active low

  for i := 0 to gc_Multiplexer_PortCount - 1 do begin
    m_PortImage[i] := 0;
  end;

end;

// Write a group of 8 outputs
// NOTE: No check whatsoever is made on parameter values
procedure Multiplexer_Write(_Port: Byte absolute m_Port; _Value: Byte absolute m_Value);
begin

  m_PortImage[_Port] := _Value;

  PORTC := (LATC and $F8) or Port; // Put address on PORTC<2:0>
  PORTD := _Value; // Put value on PORTD
  PORTC.3 := 0; // Enable latches
  PORTC.3 := 1; // Disable latches
  // Necessary NOPs were intentionally omitted :P

end;

// Write a group of 8 outputs only if its value has not changed
// This *looks* useless, but actual multiplexing is often more complex
// than the one imagined here and writing on an output port may be
// rather time-consuming, especially if done lots of times in an ISR.
procedure Multiplexer_WriteIfChanged(_Port: Byte absolute m_Port; _Value: Byte absolute m_Value);
begin

  if _Value = m_PortImage[_Port] then Exit;

  // Parameters are already in place!
  asm
    BRA     _Multiplexer_Write
  end;

end;

// Change only the bits specified by _Mask
procedure Multiplexer_MaskedWrite(_Port: Byte absolute m_Port; _Mask: Byte; _Value: Byte absolute m_Value);
begin

  _Value := (_Value and _Mask) or (m_PortImage[_Port] and not _Mask);

  // Parameters are already in place!
  asm
    BRA     _Multiplexer_Write
  end;

end;

// Remind me what I wrote to a port
function Multiplexer_ReadBack(_Port: Byte absolute m_Port): Byte;
begin

  Result := m_PortImage[_Port];

end;

end.
The above unit will compile only in my wildest dreams, at least for now. ;) A version without absolute parameters wastes both time and RAM, because parameters need to be copied before calling Multiplexer_Write.

Post Reply

Return to “mikroPascal Wish List”