Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 22:59 09 May 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : 'flags' in interrupt routine

     Page 1 of 2    
Author Message
58kk90
Regular Member

Joined: 14/06/2023
Location: United Kingdom
Posts: 59
Posted: 02:46pm 05 Mar 2025
Copy link to clipboard 
Print this post

Another 'numpty' question from a newbie.

I have started playing with pin change interrupts on the Pico, and as the manual says the idea is to have as little going on in the actual intetrupt routine as possible, generally just set a flag to indicate something changed etc.

In previous micro's (going back to 8048 / 8051 and then PIC and Arduino ) I would have a byte called for example 'flags' then set individual bits to indicate the event, i'd set each bit in the interrupt routine and then clear it in the main code.

In Pico basic, there doesn't seem to be a byte variable type, which is fine, but how do you folks flag that something has changed in the interupt routine without using a 64bit variable for each event, which seems quite wasteful to me.

Obviously I coud do this

Dim PinChanged as integer
PinChanged =  0

then in the interrupt routine set PinChanged to '1' and then act on it in the main program and set it back to zero, but I feel there must be a better and more efficient way that uses less variable space as it is only using a single 'bit' out of each 64 bit integer variable, if there are lots of different flags does that not use up valuable ram space?

Or is there enough variable space that I need not worry about it and do  it the way I suggested above?

Tony
 
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1526
Posted: 03:04pm 05 Mar 2025
Copy link to clipboard 
Print this post

Hi Tony,
one possibility would be to use 1-byte strings (actually 2 bytes = Dim myflag$ string  LENGTH 1). The decoding effort would probably cancel out the benefit.
I wouldn't worry about the memory consumption for integers at first, only for very large projects.
Regards
Michael

I recently considered using the individual bits of an integer as flags for selected files in the file manager, but that's not worth the extra effort.
Edited 2025-03-06 01:16 by twofingers
causality ≠ correlation ≠ coincidence
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3309
Posted: 03:39pm 05 Mar 2025
Copy link to clipboard 
Print this post

As Michael suggests, other than for exceptionally large programs, it is a waste of valuable programmer time to try to save extraordinarily cheap bits in MMBasic.

So don't sweat the small stuff, and save your effort for the main chance.

(As a one-time Z80 programmer, I understand the compulsion--if it drives you to save those bits, Cap'n Boing has routines on FruitOfTheShed ( FOTS  ).)
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4251
Posted: 03:58pm 05 Mar 2025
Copy link to clipboard 
Print this post

Hi @twofingers,

  twofingers said  one possibility would be to use 1-byte strings (actually 2 bytes = Dim myflag$ string  LENGTH 1).


I've not explicitly checked the PicoMite firmware but I don't think that works the way you think it does. All memory allocation in MMBasic is in 256 byte blocks and as a result all (scalar) strings take 256 bytes from the heap, the LENGTH specifier only applies when allocating arrays of strings.

I *think* that Peter added a hack to the Colour Maximite 2 firmware that allows very small strings 1 - 7 (or maybe 8) characters to be stored with the variable storage rather than on the heap but I don't think that hack is present on the PicoMite ... Peter may correct me.

In answer to the OP you can use PEEK and POKE to access single bytes of an INTEGER or engage in bit twiddling, e.g. https://github.com/thwill1000/mmbasic-sptools/blob/master/src/splib/bits.inc or whatever the Captain has posted on https://fruitoftheshed.com.

Best wishes,

Tom
Edited 2025-03-06 02:02 by thwill
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1526
Posted: 04:27pm 05 Mar 2025
Copy link to clipboard 
Print this post

@Tom,
Thanks for the hint, I think you're right, I vaguely remember.
The manual doesn't help here either.
Best regards
Michael
causality ≠ correlation ≠ coincidence
 
PhenixRising
Guru

Joined: 07/11/2023
Location: United Kingdom
Posts: 1139
Posted: 04:47pm 05 Mar 2025
Copy link to clipboard 
Print this post

  58kk90 said  Another 'numpty' question from a newbie.

but how do you folks flag that something has changed in the interupt routine without using a 64bit variable for each event, which seems quite wasteful to me.



For efficient serial binary transfers, I set bits:


dim integer a

a=a or 1
a=a or 2
a=a or 4
a=a or 8
a=a or 16
a=a or 32
a=a or 64
a=a or 128

'a now equals 255

if a and 2 then
 a = a xor 2 ' reset the flag
end if

'a now equals 253


 
58kk90
Regular Member

Joined: 14/06/2023
Location: United Kingdom
Posts: 59
Posted: 05:11pm 05 Mar 2025
Copy link to clipboard 
Print this post

Thank you to all who replied, I guess it's use a single variable for each flag bit then.

@PhenixRising that is probably very close to how I would have eventually done it had I used a single variable for all flags, I wondered if there was something along the line of flags.1 for bit 1 or flags.2 for bit 2 and so on and it just wasn't documented,
but I guess that would require 'flags' to be a byte variable, which we don't have.

Tony.
 
ville56
Senior Member

Joined: 08/06/2022
Location: Austria
Posts: 217
Posted: 05:13pm 05 Mar 2025
Copy link to clipboard 
Print this post

I usually define bitmasks as constants with meaningful names. AND and OR operators do the setting and testing. So i can use a single integer as an eventflag cluster for up to 64 flags.

Regards
Gerald
                                                                 
73 de OE1HGA, Gerald
 
PhenixRising
Guru

Joined: 07/11/2023
Location: United Kingdom
Posts: 1139
Posted: 06:00pm 05 Mar 2025
Copy link to clipboard 
Print this post

  ville56 said  I usually define bitmasks as constants with meaningful names. AND and OR operators do the setting and testing. So i can use a single integer as an eventflag cluster for up to 64 flags.

Regards
Gerald


Sure but unlike a compiler, the constants are not replaced with literals and so the interpreter loses time finding the value of those constants, right?

I haven't heard much about MMReplace but from what I understand, it's a post-processor(?) where constants and long variable names can be replaced just prior to sending to the Mite(?)
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 2139
Posted: 07:44pm 05 Mar 2025
Copy link to clipboard 
Print this post

  58kk90 said  

In previous micro's (going back to 8048 / 8051 and then PIC and Arduino ) I would have a byte called for example 'flags' then set individual bits to indicate the event, i'd set each bit in the interrupt routine and then clear it in the main code.


like this?
https://fruitoftheshed.com/wiki/doku.php?id=mmbasic:bit_manipulation_functions

I use these routines (and my timer pack) ***EXTENSIVELY*** in my code. actually the ones I use are really optimised for speed. I can post that if you want
Edited 2025-03-06 05:47 by CaptainBoing
 
ville56
Senior Member

Joined: 08/06/2022
Location: Austria
Posts: 217
Posted: 08:11pm 05 Mar 2025
Copy link to clipboard 
Print this post

Sure  you can either optimize runtime or memory consumption. Variable names are hashed as i understood to speed up the lookup. But it still is an interpreter.
                                                                 
73 de OE1HGA, Gerald
 
PhenixRising
Guru

Joined: 07/11/2023
Location: United Kingdom
Posts: 1139
Posted: 08:54pm 05 Mar 2025
Copy link to clipboard 
Print this post

@CaptainBoing

  Quote  'Clear a flag
Sub FlagRes(b As Integer)
Flag=Flag Or &o1<<b Xor &o1<<b
End Sub


So we OR followed by XOR to clear a bit whose state is not known.

In other BASICs I can use AND NOT to achieve the same. Doesn't work in MMBasic though.
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 3998
Posted: 09:27pm 05 Mar 2025
Copy link to clipboard 
Print this post

Unless you're desperate for every byte of memory just (KISS) use one variable per flag. Easy to read, easy to write, easy to maintain, easy to reuse.

It'll be much faster than some of the stuff just posted, too, especially in the interrupt routine.

John
 
ville56
Senior Member

Joined: 08/06/2022
Location: Austria
Posts: 217
Posted: 09:39pm 05 Mar 2025
Copy link to clipboard 
Print this post

use INV instead of NOT.

e.g. Flag=Flag and inv (1<<b)

should work this way ....
                                                                 
73 de OE1HGA, Gerald
 
PhenixRising
Guru

Joined: 07/11/2023
Location: United Kingdom
Posts: 1139
Posted: 10:18pm 05 Mar 2025
Copy link to clipboard 
Print this post

  ville56 said  use INV instead of NOT.

e.g. Flag=Flag and inv (1<<b)

should work this way ....


I don't believe so (away from my PicoMite)

If the flag is already zero and I want to set to zero, INV will make it a one.

Using OR and XOR works because OR will always set the flag to a one, no matter the existing state.
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 3998
Posted: 11:48pm 05 Mar 2025
Copy link to clipboard 
Print this post

  ville56 said  use INV instead of NOT.

e.g. Flag=Flag and inv (1<<b)

should work this way ....

Looks OK.

PRINT HEX$(INV (1<<b))

can be used to check.

John
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 2415
Posted: 04:01am 06 Mar 2025
Copy link to clipboard 
Print this post

  Quote  Looks OK.
Yes.
> a=3 : b=4 : c=0 'a, b = individual flags, c = 64 bit combined flags
> c = c or (1<<a) :? bin$(c,64) 'set flag a in c
0000000000000000000000000000000000000000000000000000000000001000
> c = c or (1<<b) :? bin$(c,64) 'set flag b in c
0000000000000000000000000000000000000000000000000000000000011000
> c = c and (inv (1<<a)) :? bin$(c,64) 'reset flag a
0000000000000000000000000000000000000000000000000000000000010000
> c = c and (inv (1<<a)) :? bin$(c,64) 'repeat to check that flag a doesn't invert
0000000000000000000000000000000000000000000000000000000000010000
>

But as previously mentioned it saves very little.
More could be saved by putting a number of short strings in one string with mid$().
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 4854
Posted: 06:58am 06 Mar 2025
Copy link to clipboard 
Print this post

I do not know your application.
But if speed is some form of important, use 64bit integers.

The math the ARM must do to execute most commands is peanuts compared to the time it takes the interpreter to decode the basic command.

In general: fewer basic commands = higher speed.

so

a%=pin(gp0)
if a% then


is so much faster than manipulating bits in a 64 bit integer.

Volhout
PicomiteVGA PETSCII ROBOTS
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 7499
Posted: 07:55am 06 Mar 2025
Copy link to clipboard 
Print this post

Agreed. Especially in an interrupt routine where you don't want to hang about.
You can do bit twiddling elsewhere, but I wouldn't recommend it in interrupts.
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 3998
Posted: 07:55am 06 Mar 2025
Copy link to clipboard 
Print this post

  phil99 said  More could be saved by putting a number of short strings in one string with mid$().

Yes, at the cost of a slower interrupt routine.

I'd go for an integer flag to keep the interrupt routine short, simple and fast.

Saving maybe 7 bytes doesn't seem vital.

Using a string has memory overheads, too, so I'd go for bits within an integer if I was absolutely desperate for RAM space (which seems vanishingly unlikely to this extent).

John
 
     Page 1 of 2    
Print this page
The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025