Recent

Author Topic: Pascal-ish Syntax for bit access.  (Read 30072 times)

Edson

  • Hero Member
  • *****
  • Posts: 1301
Re: Pascal Syntax for bit access.
« Reply #15 on: March 30, 2017, 04:36:00 pm »
I am developing a Pascal Compiler, […]
:o You're developing a compiler? Oy.
The FPC doesn't suit your case, or what? You know, you're welcome to contribute, don't you [rhetorical]?
FPC doesn't compile to Microchip PIC devices. I think this project is a contribution to FPC.

Or do you want that as an additional language construct to all types, in order to disclose the internal memory structure?
Yes. I think that's the point.

PS: The topic's title reads “Pascal Syntax for bit access.”. Well, to be fair you'd like to come up with some Pascal-ish syntax. ;)
OK. I thought to use that title. I will change.
Lazarus 2.2.6 - FPC 3.2.2 - x86_64-win64 on Windows 10

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Pascal Syntax for bit access.
« Reply #16 on: March 30, 2017, 04:43:36 pm »
Thank you for the additional information marcov.

FPC only supports absolute to addresses on dos (and I assume the embedded targets). You might want to checkout the CPU specific headers of the various embedded targets that FPC supports (avr,arm,m68k)
Hmz, it compiles fine for me for whatever target i chose (it doesn't make real sense of course so a (edit: runtime error 216) crash will most likely  happen when read from/written to). Assuming you meant a simple variable declaration pointing to an absolute address.

Indeed works and makes sense for targets like m68k and arm.

edit: striped/replaced
« Last Edit: March 30, 2017, 04:55:03 pm by molly »

Edson

  • Hero Member
  • *****
  • Posts: 1301
Re: Pascal-ish Syntax for bit access.
« Reply #17 on: March 30, 2017, 05:23:47 pm »
The embedded world with its memory mapped special function registers  is full of this.
Yes. My idea is to have a Pascal unit, for each device, with definitions about the registers and bits of that device.

So the .SOMEBIT is probably using a declaration of a record like I posted (and Molly posted the C equivalent syntax), and the variablename.0   (.bitnumber) syntax is a different extension.
Yes. That differente extension, is useful, I would like to include in the compiler, but I'm afraid it breaks the Pascal Philosophy.

Note that microchips only can access addresses under 8192 at bitlevel. (this is where most registers are)
No problem. It's in most cases, all the addressed memory in a embedded system.

The convention in Microchip own compilers is usually that if there is a byte level register MYREG at address 50, there are two declarations. One byte typed is called MYREG, and one with a record to access named bits called MYREGbits, so with -bits appended.  They are then put on the same address using a variant of absolute (to place them on a hardcoded address, rather than a different variable).
I think it's the most reasonable way in Pascal, and C. I can implement this:

Code: Pascal  [Select][+][-]
  1. VAR
  2.   STATUS: byte absolute $03;
  3.   STATUSbits: bitpacked record  //need a type first? It's easier like this.
  4.                                  C : TBit;
  5.                                  DC: TBit;
  6.                                  Z : TBit;
  7.                                  PD: TBit;
  8.                                  TO : TBit;
  9.                                  RP : 0..3; // two bits.
  10.                                  IRP : TBit;
  11.                      end absolute STATUS;
  12.  
And it will be needed to declare for all the registers.

But what about is the programmer wants to declare a variable, and then access to individual bits.

Code: Pascal  [Select][+][-]
  1. VAR
  2.   myVar: byte;
  3. ...
  4.   myVar.0 := 1;  //I really want to do this
  5.  

It will be really hard to force the programmer to use a bitpacked register, just for changing a bit.

I don't use mikro's compiler variants, so I don't know if they follow the same convention.

Well. MikroPascal, and Pic Micro Pascal, let use something like "PORTA.0" or "STATUS.C".
Lazarus 2.2.6 - FPC 3.2.2 - x86_64-win64 on Windows 10

avra

  • Hero Member
  • *****
  • Posts: 2514
    • Additional info
Re: Pascal-ish Syntax for bit access.
« Reply #18 on: March 30, 2017, 06:38:24 pm »
The embedded world with its memory mapped special function registers  is full of this.
Yes. My idea is to have a Pascal unit, for each device, with definitions about the registers and bits of that device.
You should really take a look at E-Lab's AvrCo Pascal. When installed you will find hundreds of DSC files. One for each microcontroller device. Exactly as you describe.

So the .SOMEBIT is probably using a declaration of a record like I posted (and Molly posted the C equivalent syntax), and the variablename.0   (.bitnumber) syntax is a different extension.
Yes. That differente extension, is useful, I would like to include in the compiler, but I'm afraid it breaks the Pascal Philosophy.
No it doesn't. It really makes code look much more friendly. Each byte, word, longword and quadword variable bits can be accessed with dot bit number syntax. Take a look at how clean and clear these definitions look like, and imagine how would they look using only what Knuth left us:

Code: Pascal  [Select][+][-]
  1.   { PORTA }
  2.   AIN0   [@PinA, 0]: bit; // analog input
  3.   DI     [@PORT_STABLE1]: byte; // debounced input pin
  4.   DI1    [@PinA, 0]: bit; // Input PIN without need for debouncing
  5.   SW1    [@PORT_STABLE1, 6]: bit;            // Input PIN     DIP switch 1
  6.   SW2    [@PORT_STABLE1, 7]: bit;            // Input PIN     DIP switch 2
  7.  
  8.   { PORTB }
  9.   PWMA   [@PortB, 5]: bit;      // Output PIN -
  10.   PWMB   [@PortB, 6]: bit;      // Output PIN -
  11.  
  12.   { PORTC }
  13.   DO     [@PortC]: byte;
  14.   DO1    [@PortC, 4]: bit;   // Output PIN -
  15.   Buzzer [@PortC, 5]: bit; // Output PIN
  16.   SysLed [@PortC, 6]: bit;   // Output PIN - SYS LED
  17.  

So now we can use such code:

Code: Pascal  [Select][+][-]
  1.    MyInput := DI.0;
  2.    MyInput := DI1; // the same as previous line
  3.  
  4.    DO.5   := 1;
  5.    Buzzer := true; // the same as previous line
  6.  
  7.    SysLed := ON; // if we defined ON constant to be 1 or true
  8.  
« Last Edit: March 30, 2017, 06:42:03 pm by avra »
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: Pascal-ish Syntax for bit access.
« Reply #19 on: March 30, 2017, 06:38:32 pm »
and the variablename.0   (.bitnumber) syntax is a different extension.
Yes. That differente extension, is useful, I would like to include in the compiler, but I'm afraid it breaks the Pascal Philosophy.

Well, that never stopped FPC devels, like e.g. case of string

Quote
Note that microchips only can access addresses under 8192 at bitlevel. (this is where most registers are)
No problem. It's in most cases, all the addressed memory in a embedded system.

Well, my PICs have 28kb (mu806,mu810) or 56kb memory. (mu814)

Quote
But what about is the programmer wants to declare a variable, and then access to individual bits.

I've had many such problems, but nearly always I had the bitnr also in an variable,
how often does this happen without using a variable bitnr? Most cases are covered with the predefined records, like Avra's code pieces.

Quote
It will be really hard to force the programmer to use a bitpacked register, just for changing a bit.

Is it really hard if it is a noncommon case?

« Last Edit: March 30, 2017, 06:40:51 pm by marcov »

Edson

  • Hero Member
  • *****
  • Posts: 1301
Re: Pascal-ish Syntax for bit access.
« Reply #20 on: March 30, 2017, 07:55:20 pm »

Code: Pascal  [Select][+][-]
  1.   { PORTA }
  2.   AIN0   [@PinA, 0]: bit; // analog input
  3.   DI     [@PORT_STABLE1]: byte; // debounced input pin
  4.   DI1    [@PinA, 0]: bit; // Input PIN without need for debouncing
  5.   SW1    [@PORT_STABLE1, 6]: bit;            // Input PIN     DIP switch 1
  6.   SW2    [@PORT_STABLE1, 7]: bit;            // Input PIN     DIP switch 2
  7.  
  8.   { PORTB }
  9.   PWMA   [@PortB, 5]: bit;      // Output PIN -
  10.   PWMB   [@PortB, 6]: bit;      // Output PIN -
  11.  
  12.   { PORTC }
  13.   DO     [@PortC]: byte;
  14.   DO1    [@PortC, 4]: bit;   // Output PIN -
  15.   Buzzer [@PortC, 5]: bit; // Output PIN
  16.   SysLed [@PortC, 6]: bit;   // Output PIN - SYS LED
  17.  

This syntax is some strange. I prefer something more like Turbo Pascal:

Code: Pascal  [Select][+][-]
  1.  
  2.   PWMA : bit ABSOLUTE  PORTB.5; //or maybe "PORTB, 5" or "PORTB[5]"
  3.   PWMB : bit ABSOLUTE  PORTB.6;
  4.  

By now, I think the best way would be to have an intrinsic access to bits for all byte or words variables, using <variable name>.<number>

But the problem is still, how to define a register with named bits. The formal way:

Code: Pascal  [Select][+][-]
  1. VAR
  2.   STATUS: byte absolute $03;
  3.   STATUSbits: bitpacked record  //need a type first? It's easier like this.
  4.                                  C : TBit;
  5.                                  DC: TBit;
  6.                                  Z : TBit;
  7.                                  PD: TBit;
  8.                                  TO : TBit;
  9.                                  RP : 0..3; // two bits.
  10.                                  IRP : TBit;
  11.                      end absolute STATUS;
  12.  

results too large for me, considering that others compilers can do: "STATUS.C := 0". But it's the best option I see by now.
« Last Edit: March 30, 2017, 07:57:56 pm by Edson »
Lazarus 2.2.6 - FPC 3.2.2 - x86_64-win64 on Windows 10

avra

  • Hero Member
  • *****
  • Posts: 2514
    • Additional info
Re: Pascal-ish Syntax for bit access.
« Reply #21 on: March 31, 2017, 12:43:55 am »
But the problem is still, how to define a register with named bits.
I already did that. Sorry if that was not clear.

Btw, AvrCo has one very nice feature. Any variable can be made atomic, so read/write happens with interrupts off. Since we may have many tasks/processes, this is very convenient. Here is an example:

Code: Pascal  [Select][+][-]
  1. var
  2.   MyAtomicVar: int64, locked; // with "locked" we say that we want atomic access for this variable
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

Edson

  • Hero Member
  • *****
  • Posts: 1301
Re: Pascal-ish Syntax for bit access.
« Reply #22 on: March 31, 2017, 03:25:29 am »
Btw, AvrCo has one very nice feature. Any variable can be made atomic, so read/write happens with interrupts off.

OK. I will consider this later, and include if I see is useful.

But the problem is still, how to define a register with named bits.
I already did that. Sorry if that was not clear.
 

Maybe I was not clear. My idea is to have some kind of declaration like this:

Code: Pascal  [Select][+][-]
  1. VAR
  2.   STATUS: byte ABSOLUTE $03 RECORD
  3.                                  C : Bit;
  4.                                  DC: Bit;
  5.                                  Z : Bit;
  6.                                  PD: Bit;
  7.                                  TO : Bit;
  8.                                  RP : 0..3; // two bits.
  9.                                  IRP : Bit;
  10.                      END;
  11.  

So I can do, later:

Code: Pascal  [Select][+][-]
  1.  
  2.   STATUS := $FF;
  3.   STATUS.C := 1;
  4.   STATUS.IRP := 0;
  5.  

Does AvrCo can do this?
Lazarus 2.2.6 - FPC 3.2.2 - x86_64-win64 on Windows 10

avra

  • Hero Member
  • *****
  • Posts: 2514
    • Additional info
Re: Pascal-ish Syntax for bit access.
« Reply #23 on: March 31, 2017, 03:54:11 pm »
Does AvrCo can do this?
No, bit packed records are not supported. But bit packed sets are. So are the properties and overlays. And bits do not need to be 0..7 numbers - they can be constants. So if you write something like this:
Code: Pascal  [Select][+][-]
  1. const
  2.   Z: byte = 2;
  3.   PD: byte = 3;
  4.   IRP: byte = 7;
  5. type
  6.   TStatusBits = (sbCX {0}, sbDC {1}, sbZ {2}, sbPD {3}, sbTO {4}, sbIRP = 7);
  7.   TStatusBitset = Bitset of TStatusBits;
  8. var
  9.   STATUS       [$03]: byte;
  10.   STATUS_Z     [@STATUS, 2]: bit;
  11.   STATUS_PD    [@STATUS, 3]: bit;
  12.   STATUS_IRP   [@STATUS, 7]: bit;
  13.   StatusBitset [@STATUS]: TStatusBitset;
  14.  
  15. property
  16.   RP: byte read GetRP write SetRP;
  17.  
  18. procedure SetRP(b: byte); // setter
  19. begin
  20.   STATUS.5 := b.0;
  21.   STATUS.6 := b.1;
  22. end;
  23.  
  24. function GetRP: byte;     // getter
  25. begin
  26.   return(byte(STATUS.5) + (byte(STATUS.6) shl 1));
  27. end;
  28.  

then something like this is possible:
Code: Pascal  [Select][+][-]
  1. begin
  2.   STATUS.Z := true;
  3.   STATUS_Z := 1;
  4.   Incl(StatusBitset, [sbZ]); // exactly the same as previous 2 lines
  5.  
  6.   STATUS.IRP := 0;
  7.   STATUS_IRP := false;
  8.   Excl(StatusBitset, [sbIRP]); // exactly the same as previous 2 lines
  9.  
  10.   STATUS.3 := 0;                // PD bit
  11.   Toggle(StatusBitset, [sbPD]); // invert PD bit
  12.   if sbPD in StatusBitSet then  // the same as "if STATUS.PD then"
  13.     Toggle(STATUS.PD);          // invert PD bit
  14.   endif;
  15.  
  16.   RP := 3; // getter and setter functions are used to set value of proper bits
  17. end;
  18.  

 :D

ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

Edson

  • Hero Member
  • *****
  • Posts: 1301
Re: Pascal-ish Syntax for bit access.
« Reply #24 on: March 31, 2017, 07:21:18 pm »
Thanks @avra. Your opinion and that of the others, really helps me on this project  :).

USING SETS
=========

Code: Pascal  [Select][+][-]
  1. type
  2.   TStatusBits = (sbCX {0}, sbDC {1}, sbZ {2}, sbPD {3}, sbTO {4}, sbIRP = 7);
  3.   TStatusBitset = Bitset of TStatusBits;
  4. var
  5.   STATUS       [$03]: byte;
  6.   StatusBitset [@STATUS]: TStatusBitset;
  7.  

I like the packed sets, but:

1. I see is too much code to define the bits of a a simple register (define the Elements of the set, define the set type, and define other variable of set type). I need to declare many registers (probably 100 or more ) for each device (probably 100 or more). That's why I'm looking for a simple declaration.

2. FAIK, when using sets, you can only work with fileds of one bit length. What about if I want a two-bits field?

3. When using sets, the syntax, to set or clear a bit, is complicated, in comparison with just: "STATUS.C := 1"

USING BIT POSITION
==============

Code: Pascal  [Select][+][-]
  1. const
  2.   Z: byte = 2;
  3. var
  4.   STATUS       [$03]: byte;
  5. ...
  6.   STATUS.Z := true;
  7.  

I think this is the best approach for a simple bit manipulating (and it's how other compilers work).

But this way, define Z, like a global position, no only for STATUS.

I could do:

Code: Pascal  [Select][+][-]
  1.  
  2. any_other_byte_variable_nothing_to_do_with_STATUS.Z := true;
  3.  

So, it's not safe.
 
Lazarus 2.2.6 - FPC 3.2.2 - x86_64-win64 on Windows 10

Thaddy

  • Hero Member
  • *****
  • Posts: 14201
  • Probably until I exterminate Putin.
Re: Pascal-ish Syntax for bit access.
« Reply #25 on: March 31, 2017, 08:46:40 pm »

1. I see is too much code to define the bits of a a simple register (define the Elements of the set, define the set type, and define other variable of set type). I need to declare many registers (probably 100 or more ) for each device (probably 100 or more). That's why I'm looking for a simple declaration.
Automate it: write a short piece of code to generate it.
Quote
2. FAIK, when using sets, you can only work with fileds of one bit length. What about if I want a two-bits field?
Indexed properties can do that, see the wiki link I gave you before. There's even an example. Sets can do that too (include, exclude).
Quote
3. When using sets, the syntax, to set or clear a bit, is complicated, in comparison with just: "STATUS.C := 1"
It may look complicated, but sets are very powerful afterwards. Set/reset a number of pins in one go. Examine which bits are set in one go, Have pins depend on each other etc, etc.
That's why I use sets for pins when I work with hardware.
« Last Edit: March 31, 2017, 08:48:27 pm by Thaddy »
Specialize a type, not a var.

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1312
    • Lebeau Software
Re: Pascal-ish Syntax for bit access.
« Reply #26 on: March 31, 2017, 09:55:01 pm »
FAIK Object Pascal, have no support to this kind of access.

Not in the Pascal language itself, no.  However, in Delphi at least, this can be done in XE3+ using an intrinsic type helper, eg:

Code: Pascal  [Select][+][-]
  1. type
  2.   TMyByteHelper = record helper for Byte
  3.     function GetBit(Index: Byte): Boolean;
  4.     procedure SetBit(Index: Byte; Value: Boolean);
  5.     property Bit[Index: Byte]: Boolean read GetBit write SetBit;
  6.   end;
  7.  
  8. function TMyByteHelper.GetBit(Index: Byte): Boolean;
  9. begin
  10.   Result := ((Self shr Index) and $01) <> 0;
  11. end;
  12.  
  13. procedure TMyByteHelper.SetBit(Index: Byte; Value: Boolean);
  14. begin
  15.   if Value then
  16.     Self := Self or ($01 shl Index)
  17.   else
  18.     Self := Self and not ($01 shl Index);
  19. end;
  20.  
  21. var
  22.   foo: byte;
  23. ...
  24.   foo := 255;
  25.   foo.Bit[0] := true|false;  //set bit 0
  26.  

FreePascal supports helpers, but not on intrinsic types, only on records and classes.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

avra

  • Hero Member
  • *****
  • Posts: 2514
    • Additional info
Re: Pascal-ish Syntax for bit access.
« Reply #27 on: March 31, 2017, 11:03:19 pm »
Thanks @avra. Your opinion and that of the others, really helps me on this project  :).
You're most welcome. It is your compiler, so you will probably implement syntax you are most comfortable with. However, I really think you should download and study free versions of MikroElektronika and E-Lab Pascal compilers. I use both, but prefer E-Lab for most things. It's built in multitasking, visual simulator, jtag debugging and tons of drivers and examples have really saved me so much time over last 20 years. Free standard release of AVRco is limited to 4kB flash, free Mega8/Mega48 release is limited 8kB flash, and free XMega8E5..XMega32E5 release is limited to 16kBytes of flash. More then enough for most of your tests to get lots of inspiration.
http://forum.lazarus.freepascal.org/index.php/topic,32816.msg211887.html#msg211887

FreePascal supports helpers, but not on intrinsic types, only on records and classes.
Are you sure? http://www.freepascal.org/docs-html/ref/refse63.html#x124-14600010.4
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: Pascal-ish Syntax for bit access.
« Reply #28 on: April 01, 2017, 12:01:41 am »

FreePascal supports helpers, but not on intrinsic types, only on records and classes.

It does support on intrinsics in trunk afaik. The superior bitpacked syntax is available in 3.0.x. That syntax lets the compiler decide how to isolate a bit, and that is much more portable across architectures with e.g. alignment requirements.

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1312
    • Lebeau Software
Re: Pascal-ish Syntax for bit access.
« Reply #29 on: April 01, 2017, 02:29:14 am »
FreePascal supports helpers, but not on intrinsic types, only on records and classes.
Are you sure? http://www.freepascal.org/docs-html/ref/refse63.html#x124-14600010.4

Thanks, I hadn't seen that page before.  In that case, the Wiki documentation should be updated to reflect that.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

 

TinyPortal © 2005-2018