Jeff Martin said...
Each Cog gets a main bus access every system clocks, regardless of how many other cogs are running
Lost a number or somehting in there, but it sounds like the "distributor" runs at a constant rate, so the COGs receive central access at the same time, regardless of whether other are launched.
Dave
That's correct Dave.· The hub comes around at a constant rate which can help knowing exact timing where needed with other cogs running.
It boots from EEPROM?
Can it be connected to any pin?
(I can't see any pins dedicated to this function in the pictures in the catalog)
Or is that from Internal ROM?
The EEPROM needs to be on specific pins for the bootloader to find it.· Other than that, the 32 pins can be used for any functions (VGA, TV, Mouse, I2C, etc).· Remember, it's·all software based!
martin Hebel said...
PRI blink(pin, rate)
dira[noparse][[/noparse]pin]~~
repeat
waitcnt(rate<<19 + cnt)
!outa[noparse][[/noparse]pin]
What are the tildes (~~) for?
Does waitcnt put a CPG to sleep, until syscnt reaches the parameter value? Does it automatically handle wrap/overflow?
Does !outa[noparse][[/noparse]pin] amount to (pin) = !(pin) ?
>for one thing, there are 8 cogs (processors), thats ~20 MIPS * 8 = ~ 160 MIPS.
Ahem. That's kind of optimistic, in my experience of multiprocessing [noparse]:)[/noparse]
Keeping them all fed, especially with a polled backplane, is going to be a challenge, unless the job fits the chip suspiciouly well...
It does look as if this chip won't replace the SX, more open up a load of new possibilities. That'll do me - as soon as it's on general release, I'll be there, checkbook in hand, trust me.
Steve
(I've got a long and sordid multiprocessor past, so it's fascinating to watch this new architecture emerge..
Ok since Jeff has clarified what we can an cannot talk about I can answer some general tech questions.
SteveW said...
>Most instructions take 4 clock cycles, including those that access a cog's private memory
Hmm, that's quite sad - looks like the (not-)interrupt latency is going to be worse than an SX clocked hard, under most cases. That rules out a class of operation I've come to quite enjoy. It'll be interesting to see how much, if any, of that can be clawed back with the IO assistant block, whatever that turns out to be [noparse]:)[/noparse]
(I'll stop wildly speculating when I see data...)
(Hmm, pondering - I wonder if pipelining is made so much trickier by having combined code / data space, since you can't guarantee what code you'll be executing... My head hurts)
Steve
There is no latency for a cog if you program it correctly, there are a series of instruction in Spin and assembly (yes you'll be able to program in assembly as well) that tells the cog to wait on a condition (pins state, timer state, video state), the cog goes into a low power sleep state until that condition occurs, once the condition is satisified, the cog continues execution the very next master clock cycle. This does not have to be a multiple of 4 clock cycles from the exection of the wait on condition instruction, it could be 15 clock cycles or any arbitrary amount of cycles. So as long as you set the cog a proper amount of cycles·in order to catch the event, there will be absolutely no latency.
Each cog has access to the I/O block every cycle, so there is no waiting your turn for access to the I/O block. Parallax has designed it so that each cogs access to the pin state and direction is or'ed together, any cog says the pin is output, its output, any pin says a pin is high (when it is an output) its high.
Bean (Hitt Consulting) said...
Okay most of that makes sense except "dira[noparse][[/noparse]pin]~~" what does that do ?
Bean.
dira[noparse][[/noparse]pin] sets the direction regsiter for the pin.· The I/O a0-31 is all referred to as a.· In the docs you'll find dirb is reserved for I/O for a b regsiter should one ever exist in the future for another 32 I/O.
The ~~ is actually post-set to all high bits
-Martin
Jeff Martin said...
Each Cog gets a main bus access every system clocks, regardless of how many other cogs are running
Lost a number or somehting in there, but it sounds like the "distributor" runs at a constant rate, so the COGs receive central access at the same time, regardless of whether other are launched.
Dave
Think of the hub as a V8 engine, where each piston is connected at an offset to the cam. Each cog gets access to the hub in a round robin fashion (cog0, cog1, ..., cog7, cog0).
What are the tildes (~~) for?
Does waitcnt put a CPG to sleep, until syscnt reaches the parameter value? Does it automatically handle wrap/overflow?
Does !outa[noparse][[/noparse]pin] amount to (pin) = !(pin) ?
Dave
The outa and ~~ is discussed in another post.· Yes, waitcnt puts the processor in a holding pattern until the condition is met.· This is how interrupts-like events will be handled also - wait for an input(s) to match.
The math works out to handle the overflow since they are both 4 bytes (long).
Gadgetman said...
It boots from EEPROM?
Can it be connected to any pin?
(I can't see any pins dedicated to this function in the pictures in the catalog)
Or is that from Internal ROM?
Yes, it boots from an external 32kb EEPROM connected to I/O pins 28 and 29.· They are available for general purpose use after boot up.· I/O pins 30 and 31 talk to the host device (PC with USB-based adapter) after reset, then are general purpose afterwards.
My guess is that it sets the direction on the selected pin, but the ~~ bit was new to me, too...
First it reserves some data space? Possibly a stack which is 20 LongWords big,
Then it starts all the COGs with the order to run the 'blink' program using the specified IO-pin and blink-rate, and adding a stack for the program to use while looping?
And finally we get the 'blink' program itself.
Interestingly, most programming-languages I have used would not like that you use/call a program(in this case 'Blink') before defining it. (Rules of visibility. Very important in languages that supports recursion. Or maybe just in languages where the designers tried to avoid yet another pass through the source... )
Anyway, we see that variable definitions are common, and that procedures can be both PUBlic and PRIvate.
Passing variables as seen here also hints at the possibility of locally defined variables.(As it is evident that variables have different scopes to avoid confusion when named similarly)
A pot of tea(1.5Litre), cookies, and code to look at, can it get any better?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Don't visit my new website...
This "Talks to the PC with USB-based adapter", does that mean that the propeller chip really·communicates·TTL serial at a high speed (greater than 115200) and your using the FTDI chip serial to USB adapter to communicates between the PC's USB master to Propeller's high speed serial port?
Thanks,
Mike
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"OEM NMEA GPS Module" Now available on ebay for only $17.49
SteveW said...
>for one thing, there are 8 cogs (processors), thats ~20 MIPS * 8 = ~ 160 MIPS.
Ahem. That's kind of optimistic, in my experience of multiprocessing [noparse]:)[/noparse]
Keeping them all fed, especially with a polled backplane, is going to be a challenge, unless the job fits the chip suspiciouly well...
It does look as if this chip won't replace the SX, more open up a load of new possibilities. That'll do me - as soon as it's on general release, I'll be there, checkbook in hand, trust me.
Steve
(I've got a long and sordid multiprocessor past, so it's fascinating to watch this new architecture emerge..
I understand your skeptisism, but Parallax did an excellent job on this chip. Each cog has its own memory that is Von Numan (can store code and data, yes this means self modifying code is possible). In addition there is central memory located in the hub. There are two different ways of running a program on a cog, the first is assembly, this loads the program from the hub into the cog and starts executing. It is up to the program on the cog when or if to access memory in the hub, so if you can fit your program and data into the cog, and you have no need to communicate with the hub or other cogs through shared memory access, then its on its merry way executing its program. The second is running Spin code on a cog, in this instance the cog is loaded with an interpretor which loads and runs the executable bytecode on the hub, vaguely akin to the Stamp and its fetching byte code from EEPROM. Since it fetches the bytecode from the hub memory, it must wait for it's access to the hub for each new byte code.
As you can see Spin is designed to get you programming your chip quicker, like a Stamp makes it simple, and assembler allows you squeeze every ounce of power out of the chip.
Im sorry for comparing the chip to the Stamp and the SX, it is not like either of them and its not like any other multiprocessor system youve seen before. It was designed from the ground up and hence it is its own animal (even the memory on board was hand designed)·and cannot be compared to anything else. I only draw comparisions because I know that people have experience with the other Parallax products and Im trying to explain in a relational sort of way, since we cannot plop down datasheets to show you the absolute specifics.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ ·1+1=10
Post Edited (Paul Baker) : 2/20/2006 6:59:12 PM GMT
> the cog goes into a low power sleep state until that condition occurs, once the condition is satisified, the cog continues execution the very next master clock cycle
Spiffy! That'll do nicely.
Can I make it wait on more than one condition, for timeouts and cunning?
(Note, I'll wait for the data if you don't want to play 20 questions - I'm just waiting for this FPGA to route, and trying to avoid doing something very dull...)
Any comparison speedwise, running Spin on a single COG and PBasic on a BS2 or BS2p?
(I assume a certain increase in speed because of having the code available in central memory instead of having to haul it off of a 24cXX all the time)
Nice to know that pins 28 - 31 can be freed, but how?
(Unless we can disconnect the EEPROM and the USB-adapter we must be extremely careful about using those pins)
Not that it matters that much. With the possibility of dedicating COGs for IO tasks, there shouldn't be any problem stuffing shift-registers all over and multiplying the number of ports available...
Edit: Can we mix Spin and Assembler?
(Spin for the 'boring' stuff and Assembler for time-critical stuff)
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Don't visit my new website...
This "Talks to the PC with USB-based adapter", does that mean that the propeller chip really·communicates·TTL serial at a high speed (greater than 115200) and your using the FTDI chip serial to USB adapter to communicates between the PC's USB master to Propeller's high speed serial port?
Yes and no.· This is 3.3v logic.· You can communicate at high speeds, but as of yet I have not tested how fast we can go (in user programs).· But, the chip itself talks to the PC using a special serial protocol where the bits are different widths to accomodate variances in the internal 12 MHz clock that it uses at boot-up.· Yes, we use an FTDI chip, FT232R, to do the logic/protocol translation from the chip to the PC and vice versa.
Sorry Steve there is no timouts on wait conditions, you either have to be sure the condition will occur or devise a secondary means for assuring the condition. This really only happens on waiting on IO, but since you likely will only be waiting on a pin(s) condition if it was designed as an input, you can design it so that another cog (maybe waiting on a timer count) forces the condition for the waiting cog. The second cog can even override the external states of the pins by seting the pins direction to output, then setting the waited-for state in the first cog. This will wake up the first cog since it is looking at the waited for pins as an input. Using the I/O lines is another way for intercog communications.
>I understand your skeptisism, but Chip Gracey did an excellent job on this chip.
Yep - from the details so far, it's looking like a good'un.
Still very little information on the CPUs - any particularly cunning instructions? Are all opcodes 32-bit? (seems maybe a bit wasteful with such a small working set)
Any way (other than a copyright sticker) to protect code?
SteveW said...
> the cog goes into a low power sleep state until that condition occurs, once the condition is satisified, the cog continues execution the very next master clock cycle
Spiffy! That'll do nicely.
Can I make it wait on more than one condition, for timeouts and cunning?
(Note, I'll wait for the data if you don't want to play 20 questions - I'm just waiting for this FPGA to route, and trying to avoid doing something very dull...)
Steve
You can wait on a number of pins to match a specification, but I don't think you can wait for multiple things to happen (clock is this and pins are that) at once.
Well i will tell you that every assembly instruction can have a conditional execution statement (16 types are possible) and each instruction optionally affects the Z and C flag.
SteveW said...
>I understand your skeptisism, but Chip Gracey did an excellent job on this chip.
Yep - from the details so far, it's looking like a good'un.
Still very little information on the CPUs - any particularly cunning instructions? Are all opcodes 32-bit? (seems maybe a bit wasteful with such a small working set)
Any way (other than a copyright sticker) to protect code?
Steve
The op-codes themselves pack as much into a long as possible including, source and desitnation addresses, conditional which can be used in any (Z, C) and whether to set flags or not.
This allows the most bang-for-the-buck from a single 32-bit opcode!
Gadgetman said...
Nice to know that pins 28 - 31 can be freed, but how?
(Unless we can disconnect the EEPROM and the USB-adapter we must be extremely careful about using those pins)
Edit: Can we mix Spin and Assembler?
(Spin for the 'boring' stuff and Assembler for time-critical stuff)
The Host I/O pins could be left disonnected from host after development.· The EEPROM pins, of course, will still be connected to an EEPROM.· There are a few optional component scenarios, however, that may make the EEPROM pins available (ie: if you have an application that is loaded up via the host only (no EEPROM attached).
>Well i will tell you that every assembly instruction can have a conditional execution statement (16 types are possible) and each instruction optionally affects the Z and C flag.
Sweet. As a Cambridge-dweller (UK) , that all sounds very comfortably familiar [noparse]:)[/noparse]
I'd like to throw one more thing out there for those talking about the Propeller...In all the years of Windows and other Multi-tasking operating systems that word, multitasking has gotten very familiar in everyone's mind.· What we need to remember with the Propeller is that it does multiprocessing, which is a more accurate term.· In multitasking a single processor has its time split up among different tasks, while in multiprocessing each task has a dedicated processor, as is the case with the Propeller.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ Chris Savage Parallax Tech Support csavage@parallax.com
Ok, I need to change my shorts...
WOW... AWESOME!...
I can see a VERY capable hex-a-pod (better yet... octa pod...) moving about, PLAYING with the cats....
Hmmm, I take it that most of the other app-mods will be compatable with it?
..
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Just tossing my two bits worth into the bit bucket
KK ·
Comments
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Martin Hebel
Southern Illinois University Carbondale -Electronic Systems Technologies
Personal Links with plenty of BASIC Stamp info
and SelmaWare Solutions - StampPlot - Graphical Data Acquisition and Control
-Martin
·
' assign variable space for each processor
VAR
· long· stack0[noparse][[/noparse]20]
· long· stack1[noparse][[/noparse]20]
· long· stack2[noparse][[/noparse]20]
· long· stack3[noparse][[/noparse]20]
· long· stack4[noparse][[/noparse]20]
· long· stack5[noparse][[/noparse]20]
· long· stack6[noparse][[/noparse]20]
· long· stack7[noparse][[/noparse]20]
·
' start the same code in each hub controlling a different LED·
PUB start
· cognew(blink(23,1), @stack0)
· cognew(blink(22,2), @stack1)
· cognew(blink(21,3), @stack2)
· cognew(blink(20,4), @stack3)
· cognew(blink(19,5), @stack4)
· cognew(blink(18,6), @stack5)
· cognew(blink(17,7), @stack6)
· coginit(cogid, blink(16,8), @stack7)
' The private code which will be ran, being passed which pin and at what speed. cnt is the internal 32 bit counter.
PRI blink(pin, rate)
· dira[noparse][[/noparse]pin]~~
· repeat
··· waitcnt(rate<<19 + cnt)
··· !outa[noparse][[/noparse]pin]
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Martin Hebel
Southern Illinois University Carbondale -Electronic Systems Technologies
Personal Links with plenty of BASIC Stamp info
and SelmaWare Solutions - StampPlot - Graphical Data Acquisition and Control
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"SX-Video·Module" Now available from Parallax for only $28.95
http://www.parallax.com/detail.asp?product_id=30012
"SX-Video OSD module" Now available from Parallax for only·$49.95
http://www.parallax.com/detail.asp?product_id=30015
Product web site: www.sxvm.com
"Ability may get you to the top, but it takes character to keep you there."
·
What are the tildes (~~) for?
Does waitcnt put a CPG to sleep, until syscnt reaches the parameter value? Does it automatically handle wrap/overflow?
Does !outa[noparse][[/noparse]pin] amount to (pin) = !(pin) ?
Dave
Ahem. That's kind of optimistic, in my experience of multiprocessing [noparse]:)[/noparse]
Keeping them all fed, especially with a polled backplane, is going to be a challenge, unless the job fits the chip suspiciouly well...
It does look as if this chip won't replace the SX, more open up a load of new possibilities. That'll do me - as soon as it's on general release, I'll be there, checkbook in hand, trust me.
Steve
(I've got a long and sordid multiprocessor past, so it's fascinating to watch this new architecture emerge..
Each cog has access to the I/O block every cycle, so there is no waiting your turn for access to the I/O block. Parallax has designed it so that each cogs access to the pin state and direction is or'ed together, any cog says the pin is output, its output, any pin says a pin is high (when it is an output) its high.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·1+1=10
The ~~ is actually post-set to all high bits
-Martin
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Martin Hebel
Disclaimer: ANY Propeller statements made by me are subject to my inaccurate understanding of my limited time with it!
Southern Illinois University Carbondale -Electronic Systems Technologies
Personal Links with plenty of BASIC Stamp info
and SelmaWare Solutions - StampPlot - Graphical Data Acquisition and Control
Post Edited (Martin Hebel) : 2/20/2006 7:31:43 PM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·1+1=10
· dira[noparse][[/noparse]16]~~
... which is the the equivalent of:
· dira[noparse][[/noparse]16] := 1
Note that "under the hood" the double-tilde sets the selected bits to -1, which is %11111111_11111111_11111111_11111111.
By using the double tilde, you can set a group of bits:
· dira[noparse][[/noparse]16..23]~~
which makes pins A16 to A23 outputs.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
The math works out to handle the overflow since they are both 4 bytes (long).
·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Jeff Martin
· Sr. Software Engineer
· Parallax, Inc.
First it reserves some data space? Possibly a stack which is 20 LongWords big,
Then it starts all the COGs with the order to run the 'blink' program using the specified IO-pin and blink-rate, and adding a stack for the program to use while looping?
And finally we get the 'blink' program itself.
Interestingly, most programming-languages I have used would not like that you use/call a program(in this case 'Blink') before defining it. (Rules of visibility. Very important in languages that supports recursion. Or maybe just in languages where the designers tried to avoid yet another pass through the source... )
Anyway, we see that variable definitions are common, and that procedures can be both PUBlic and PRIvate.
Passing variables as seen here also hints at the possibility of locally defined variables.(As it is evident that variables have different scopes to avoid confusion when named similarly)
A pot of tea(1.5Litre), cookies, and code to look at, can it get any better?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Don't visit my new website...
This "Talks to the PC with USB-based adapter", does that mean that the propeller chip really·communicates·TTL serial at a high speed (greater than 115200) and your using the FTDI chip serial to USB adapter to communicates between the PC's USB master to Propeller's high speed serial port?
Thanks,
Mike
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"OEM NMEA GPS Module" Now available on ebay for only $17.49
Product web site: http://www.allsurplus.net/Axiom/
As you can see Spin is designed to get you programming your chip quicker, like a Stamp makes it simple, and assembler allows you squeeze every ounce of power out of the chip.
Im sorry for comparing the chip to the Stamp and the SX, it is not like either of them and its not like any other multiprocessor system youve seen before. It was designed from the ground up and hence it is its own animal (even the memory on board was hand designed)·and cannot be compared to anything else. I only draw comparisions because I know that people have experience with the other Parallax products and Im trying to explain in a relational sort of way, since we cannot plop down datasheets to show you the absolute specifics.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·1+1=10
Post Edited (Paul Baker) : 2/20/2006 6:59:12 PM GMT
Spiffy! That'll do nicely.
Can I make it wait on more than one condition, for timeouts and cunning?
(Note, I'll wait for the data if you don't want to play 20 questions - I'm just waiting for this FPGA to route, and trying to avoid doing something very dull...)
Steve
(I assume a certain increase in speed because of having the code available in central memory instead of having to haul it off of a 24cXX all the time)
Nice to know that pins 28 - 31 can be freed, but how?
(Unless we can disconnect the EEPROM and the USB-adapter we must be extremely careful about using those pins)
Not that it matters that much. With the possibility of dedicating COGs for IO tasks, there shouldn't be any problem stuffing shift-registers all over and multiplying the number of ports available...
Edit: Can we mix Spin and Assembler?
(Spin for the 'boring' stuff and Assembler for time-critical stuff)
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Don't visit my new website...
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Jeff Martin
· Sr. Software Engineer
· Parallax, Inc.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·1+1=10
Yep - from the details so far, it's looking like a good'un.
Still very little information on the CPUs - any particularly cunning instructions? Are all opcodes 32-bit? (seems maybe a bit wasteful with such a small working set)
Any way (other than a copyright sticker) to protect code?
Steve
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Martin Hebel
Disclaimer: ANY Propeller statements made by me are subject to my inaccurate understanding of my limited time with it!
Southern Illinois University Carbondale -Electronic Systems Technologies
Personal Links with plenty of BASIC Stamp info
and SelmaWare Solutions - StampPlot - Graphical Data Acquisition and Control
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·1+1=10
This allows the most bang-for-the-buck from a single 32-bit opcode!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Martin Hebel
Disclaimer: ANY Propeller statements made by me are subject to my inaccurate understanding of my limited time with it!
Southern Illinois University Carbondale -Electronic Systems Technologies
Personal Links with plenty of BASIC Stamp info
and SelmaWare Solutions - StampPlot - Graphical Data Acquisition and Control
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Jeff Martin
· Sr. Software Engineer
· Parallax, Inc.
Sweet. As a Cambridge-dweller (UK) , that all sounds very comfortably familiar [noparse]:)[/noparse]
Steve
Well, that was obvious... :{)
Dave
I just created the Propeller forum and I'll move this thread there.
Regards,
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Aristides Alvarez
Education and Technical Support Manager
aalvarez@parallax.com
Parallax, Inc. www.parallax.com
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chris Savage
Parallax Tech Support
csavage@parallax.com
Is there an implementation in SPIN for one Propeller to talk to another?
Also, are we going to keep this forum as one long thread?
Maybe a few sub-topics like "Hardware", "SPIN", and "Begging for Information" would help put some order to it.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
I wonder if this wire is hot...
WOW... AWESOME!...
I can see a VERY capable hex-a-pod (better yet... octa pod...) moving about, PLAYING with the cats....
Hmmm, I take it that most of the other app-mods will be compatable with it?
..
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Just tossing my two bits worth into the bit bucket
KK
·