USB card adapters crash Pi4

Fair comment - I've not run into that requirement, but most of the stuff I worked on was financial networks and related systems. Some had multi- currency capability, so were concerned with exchange rates rather than interest calculation.

--
--   
Martin    | martin at 
 Click to see the full signature
Reply to
Martin Gregorie
Loading thread data ...

On Mon, 4 Jan 2021 13:58:29 -0000 (UTC), Martin Gregorie declaimed the following:

M$ Excel "Currency" number type internally stores four decimal places (scaled 64-bit integer), even though only two places are displayed. It allows for the accumulation of fractional cents

formatting link

Other than my COBOL courses in the late 70s, my 35 year programming life was pretty much all floating point data with some string manipulation. Satellite ephemerides, radio wave propagation/signal strength, etc.

--
	Wulfraed                 Dennis Lee Bieber         AF6VN 
	wlfraed@ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/
Reply to
Dennis Lee Bieber

places

programming

Somewhat different to me, then: I joined ICL from Uni (so 1900, 2903 [desk-size 1900 emu on 2900 DFC hardware] and 2966 kit) writing PLAN assembler, macro-generator and COBOL on Georges 1,2,3 and VME/B), worked for small software houses after ICL, then joined Logica's finance group where my first boss was Graham Sainsbury (who designed the CHAPS network), hence financial networks, ATM networks etc.

--
--   
Martin    | martin at 
 Click to see the full signature
Reply to
Martin Gregorie

On Mon, 4 Jan 2021 12:03:27 -0000 (UTC), Martin Gregorie declaimed the following:

The base BS2 uses a PIC16C57c (the BS2e, sx, p24/p40, pe, and px all used variants of Ubicom chips -- given the lack of information online, I suspect they were custom designed for Parallax alone -- ha! "The SX line of microprocessors are produced by Ubicom, Parallax is the only authorized distributor of the chips.")

From the manual

""" All BS2 models can interpret twos complement negative numbers correctly in DEBUG and SEROUT instructions using formatters like SDEC (for signed decimal). In calculations, however, it assumes that all values are positive. This yields correct results with two?s complement negative numbers for addition, subtraction, and multiplication, but not for division """

Hmmm, Parallax finally released a Propeller 2 chip.

formatting link
and appear to have discontinued all BASIC Stamps (not a surprise -- last time I checked a BS2p was around $70 while a Propeller Quickstart is only $40.

Propellers are interesting chips... 8 simple cores running in lockstep; each core has some internal RAM for programs (so it can be different code in each core) written in assembler. The default mode is that the core is loaded with a byte-code interpreter, and SPIN programs are read from external memory. The P1 allowed one core at a time to access external memory (in sequence); the new P2 apparently allows all 8 cores to do memory I/O on each cycle.

--
	Wulfraed                 Dennis Lee Bieber         AF6VN 
	wlfraed@ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/
Reply to
Dennis Lee Bieber

lockstep;

They sound interesting. I heard of them soon after they were released, but you've just increased my knowledge about them by about 500%.

Out of pure curiosity: have you any idea how much work it would be to convert a fully debugged BS2 BASIC program into a running SPIN program?

--
--   
Martin    | martin at 
 Click to see the full signature
Reply to
Martin Gregorie

On Mon, 4 Jan 2021 17:15:45 -0000 (UTC), Martin Gregorie declaimed the following:

Probably a lot. One concept with the Propeller is that one assigns cores to do what would have been an interrupt in other chips (instead of having an interrupt, that core is in a polling loop). Also using cores for dedicated I/O protocols. The GPIOs are shared by all cogs.

Manual for the P1 is at

formatting link
Besides SPIN and Propeller ASM, there is a third-party "SimpleIDE" which provides "Propeller C"
formatting link

An old demo program:

-=-=- {{ Welcome.spin Welcome to the OpenSource PropellerIDE. To run this program: * Make sure the FTDI Chip USB driver is installed. * Connect the USB Propeller board. * Debug (F8)

The program should pause a moment, print Hello, and then toggle Propeller IO P27 repeatedly. }}

CON

_clkmode = XTAL1 + PLL16X _clkfreq = 80_000_000 OBJ ser : "Parallax Serial Terminal"

PUB start ser.start(115200) waitcnt(CLKFREQ/2+CNT) '' Wait for start up ser.str(string($d,"Hello.",$d)) blink '' '' Blink ActivityBoard LED '' PUB blink '' The start method DIRA[27] |= 1 '' Set P27 to output repeat '' Repeat forever OUTA[27] ^= 1 '' Toggle LED pin waitcnt(CLKFREQ/2+CNT) '' Wait

-=-=- And the source code for the main file from DefCon22 badge (the badge uses all cogs, one file per cog)

-=-=- '' ================================================================================================= '' '' File....... dc22_badge_master.spin '' -- for internal use only! '' -- no changes unless approved/reviewed by JonnyMac/Ryan '' '' Authors.... Jon "JonnyMac" McPhalen and Ryan "1o57" Clarke '' MIT License '' -- see below for terms of use '' '' E-mail..... snipped-for-privacy@jonmcphalen.com '' snipped-for-privacy@10000100001.org '' '' Modified for Propeller Quickstart Board (touch pads and LEDs) with Human Interface '' Device board (I/R emitter/receiver, LEDs). Also modified to read pads to set "Goon" '' mode on start-up '' Dennis L Bieber '' '' =================================================================================================

{{

Welcome to Defcon 22. This year we would like to invite you to experiment more fully with your badge -- feel free to play around with code.

You can load directly to RAM [F10] if you don't want to blast your firmware, but even if you do, we are giving you the source from the start. The source provides a nice badge template with extra objects so that you can experiment with LEDs, buttons, IR (in and out), timing, speed changes, etc.

Completing the challenge will at some point require you to 'update' your badge -- but for now, how about changing your LED pattern? It's easier than you think! If you need help, feel free to stop by the Hardware Hacking Village, or simply ask someone who has a different pattern than yours. Create a new pattern -- have fun!

}}

con { timing }

_clkmode = xtal1 + pll16x _xinfreq = 5_000_000 ' use 5MHz crystal

CLK_FREQ = ((_clkmode - xtal1) >> 6) * _xinfreq ' system freq as a constant MS_001 = CLK_FREQ / 1_000 ' ticks in

1ms US_001 = CLK_FREQ / 1_000_000 ' ticks in 1us

' speed settings for power control/reduction ' -- use with clkset() instruction

XT1_P16 = %0_1_1_01_111 ' 16x crystal (5MHz) = 80MHz XT1_PL8 = %0_1_1_01_110 XT1_PL4 = %0_1_1_01_101 XT1_PL2 = %0_1_1_01_100 XT1_PL1 = %0_1_1_01_011 RC_SLOW = %0_0_0_00_001 ' 20kHz

' program speed and terminal baud B_SPEED = 20 { MHz } T_BAUD = 57_600 { for terminal io }

IR_FREQ = 36_000 { matches receiver on DC22 badge } IR_BAUD = 2400 { max supported using IR connection } IR_BLAST = $DC22

'con ' #0, HUMAN, ARTIST, PRESS, SPEAKER, VENDOR, CONTEST, GOON, UBER, LO57 ' ' BADGE_TYPE = HUMAN

con { io pins }

RX1 = 31 ' programming / terminal TX1 = 30 SDA = 29 ' eeprom / i2c SCL = 28

PAD3 = 4 '27 ' touch pads PAD2 = 5 '26 ' HID SD slot uses 0-3, sems to conflict PAD1 = 6 '25 PAD0 = 7 '24 LED7 = 23 ' leds LED6 = 22 LED5 = 21 LED4 = 20 LED3 = 19 LED2 = 18 LED1 = 17 LED0 = 16

IR_IN = 9 '15 ' ir input IR_OUT = 8 '14 ' ir output

con { io configuration }

IS_OFF = 0 ' all bits off IS_ON = -1 ' all bits on

IS_LOW = 0 IS_HIGH = -1

IS_INPUT = 0 IS_OUTPUT = -1

con { pst formatting }

#1, HOME, GOTOXY, #8, BKSP, TAB, LF, CLREOL, CLRDN, CR #14, GOTOX, GOTOY, CLS

obj

term : "cryptofullduplexserial64" ' serial io for terminal irtx : "jm_sircs_tx" ' SIRCS output irrx : "jm_sircs_rx" ' SIRCS input prng : "jm_prng" ' random #s tmr1 : "jm_eztimer" ' asynchronous timer ee : "jm_24xx512" ' eeprom access pwm : "jm_pwm8" ' pwm for LEDs btn : "touch buttons" ' QuickStart buttons are more sensitive?

var

long ms001 ' system ticks per millisecond long us001 ' system ticks per microsecond byte BADGE_TYPE 'TBD -- change type on boot

pub main | idx, last, button setup ' setup badge io and objects

term.tx(CLS) ' clear the terminal

if (BADGE_TYPE => GOON) ' check badge type alien_badge

' non-Goon badge code here

repeat until (read_pads %0000) ' wait for a pad press idx := (prng.random >> 1) // 13 repeat (idx > 1) // 13 term.caesar(@@Commands[idx]) if (check_ir) quit pause(250)

term.tx(CLS) term.caesar(@Greets) term.tx(CR) term.otp(@Test3, @Test4) term.tx(CR)

last := -1 ' any button to start repeat repeat check_ir ' check ir process button := read_pads ' wait for input until ((button %0000) and (button last)) ' must be new last := button ' save for next check case button %0001: start_animation(@Cylon, 0) ' start animation term.caesar(@Detective) ' display crypto string pause(250) ' allow clean button release %0101: start_animation(@Chaser, 0) term.otp(@Scientist, @Driver) pause(250) %0111: start_animation(@Police, 0) term.caesar(@Diver) pause(250) %1000: start_animation(@InOut, 0) term.otp(@Politician, @Football) pause(250) %1001: stop_animation term.otp(@RayNelson, @Mystery) pause(250)

pub check_ir | code

code := irrx.rxcheck ' check ir input if (code < 0) ' abort if waiting return

if (code == IR_BLAST) start_animation(@Blasted, 3) term.caesar(string($0A, "DROI VSFO GO CVOOZ", CR)) ' THEY LIVE WE SLEEP repeat while (anicog) ' let animation finish irrx.enable

if (code == IR_BLAST) return TRUE

pub alien_badge | btns, delay

'' Badge code for >= Goon

delay := -1 ' force immediate broadcast

repeat btns := read_pads if ((read_pads) or (tmr1.seconds => delay)) ' pad input or delay expired? irtx.tx(IR_BLAST, 16, 3) ' blast the humans! 'term.caesar(string($0C, "IQ XUHQ FTQK EXQQB", CR)) ' WE LIVE THEY SLEEP start_animation(@Blasted, 3) ' play blaster animation tmr1.start ' restart timer delay := ||(prng.random) // 11 + 10 ' new delay

pub setup

'' Setup badge IO and objects '' -- set speed before starting other objects

set_speed(B_SPEED) ' set badge speed (MHz) set_leds(%00000000) ' LEDs off

term.start(RX1, TX1, %0000, T_BAUD) ' start terminal

prng.seed(cnt 2) ' seed prng (random #s)

btn.Start(CLK_FREQ / 100) ' start button reading process

BADGE_TYPE := HUMAN 'read_pads ' somehow need to set up on pads if (BADGE_TYPE < GOON) irrx.start(IR_IN) ' start ir input irrx.enable ' accept ir input now else irtx.start(IR_OUT, IR_FREQ) ' start ir output tmr1.start ' start timer

con

{ ----------------------------- } { B A D G E F E A T U R E S } { ----------------------------- }

pub set_speed(mhz)

'' Sets badge clock speed '' -- sets timing variables ms001 and us001 '' -- note: objects may require restart after speed change

case mhz 0: clkset(RC_SLOW, 20_000) ' super low power -- sleep mode only! 5: clkset(XT1_PL1, 5_000_000) 10: clkset(XT1_PL2, 10_000_000) 20: clkset(XT1_PL4, 20_000_000) 40: clkset(XT1_PL8, 40_000_000) 80: clkset(XT1_P16, 80_000_000)

waitcnt(cnt + (clkfreq / 100)) ' wait ~10ms

ms001 := clkfreq / 1_000 ' set ticks per millisecond for waitcnt us001 := clkfreq / 1_000_000 ' set ticks per microsecond for waitcnt

pub set_leds(pattern)

'' Sets LED pins to output and writes pattern to them '' -- swaps LSB/MSB for correct binary output

outa[LED0..LED7] := pattern ' write pattern to LEDs dira[LED0..LED7] := IS_HIGH ' make LED pins outputs

pub read_pads | btns, lwr, upr, wid

lwr := PAD3 255, duplicate pattern + delay

Cylon byte (@Cylon_X - @Cylon) / 2 + 1 byte %10000000, 125 byte %01000000, 125 byte %00100000, 125 byte %00010000, 125 byte %00001000, 125 byte %00000100, 125 byte %00000010, 125 byte %00000001, 125 byte %00000010, 125 byte %00000100, 125 byte %00001000, 125 byte %00010000, 125 byte %00100000, 125 Cylon_X byte %01000000, 125

Chaser byte (@Chaser_X - @Chaser) / 2 + 1 byte %10010010, 75 byte %00100100, 75 Chaser_X byte %01001001, 75

InOut byte (@InOut_X - @InOut) / 2 + 1 byte %10000001, 100 byte %01000010, 100 byte %00100100, 100 byte %00011000, 100 byte %00100100, 100 InOut_X byte %01000010, 100

Police byte (@Police_X - @Police) / 2 + 1 byte %11001100, 75 byte %11110000, 75 byte %11001100, 75 byte %11110000, 75 byte %00001111, 75 byte %00110011, 75 byte %00001111, 75 Police_X byte %00110011, 75

Blasted byte (@Blasted_X - @Blasted) / 2 + 1 byte %00000000, 50 byte %00011000, 50 byte %00111100, 50 byte %01111110, 50 byte %11111111, 50 byte %00000000, 50 byte %00011000, 50 byte %00111100, 50 byte %01111110, 50 byte %11111111, 50 byte %00000000, 50 byte %00011000, 50 byte %00111100, 50 byte %01111110, 50 byte %11111111, 50 byte %00000000, 50 byte %11111111, 50 byte %00000000, 50 byte %11111111, 50 byte %00000000, 50 byte %11111111, 50 byte %00000000, 50 byte %11111111, 50 byte %00000000, 50 byte %11111111, 50 Blasted_X byte %00000000, 50 con

{ ------------- } { B A S I C S } { ------------- }

pub pause(ms) | t

'' Delay program in milliseconds '' -- ensure set_speed() used before calling

t := cnt ' sync to system counter repeat (ms #>= 0) ' delay > 0 waitcnt(t += ms001) ' hold 1ms

pub high(pin)

'' Makes pin output and high

outa[pin] := IS_HIGH dira[pin] := IS_OUTPUT

pub low(pin)

'' Makes pin output and low

outa[pin] := IS_LOW dira[pin] := IS_OUTPUT

pub toggle(pin)

'' Toggles pin state

!outa[pin] dira[pin] := IS_OUTPUT

pub input(pin)

'' Makes pin input and returns current state

dira[pin] := IS_INPUT

return ina[pin]

pub pulse_out(pin, us) | state

'' Generate pulse on pin for us microseconds '' -- ensure set_speed() used before calling '' -- makes pin output '' -- pulse out is opposite of pin's input state '' -- blocks until pulse is finished (to clear counter)

us *= us001 ' convert us to system ticks state := ina[pin] ' read incoming state of pin

if (ctra == 0) ' ctra available? if (state == 0) ' low-high-low low(pin) ' set to output frqa := 1 phsa := -us ' set timing ctra := (%00100

Reply to
Dennis Lee Bieber

On a sunny day (Mon, 04 Jan 2021 14:03:31 -0500) it happened Dennis Lee Bieber wrote in :

If I read this it makes me wonder why not go FPGA, learn Verilog for example. Then you can basically create your own processor, cores, and it is widely used and proven technology, also with a wide experimental open source user base:

formatting link
make your own processor, elect one!:
formatting link

FPGA boards are cheap on ebay these days. It also enhances your value on the IT market. It helps to have hardware design experience. IIRC there also is an FPGA HAT for Raspberry.

Design your own processor, with your own instruction set... Sky is the limit, as is speed it seems.

Reply to
Jan Panteltje

Money should use Fixed type.

Reply to
Björn Lundin

Depends: Thats OK for a single currency system, but if you need to handle multi-currency, then you need at least three variables to describe a financial amount:

long int value; int decimalPlace; String currencyName;

where value is the value in the smallest legal unit (pence for GBP, cents for Euros or dollars and decimalPlace (2 for GBP and most other currencies, though IIRC there are a few that use 3 decilal places, is only used when converting to or from human-readable strings.

In practise you may need quite a complex currency parser, because a lot of bankers and finance traders would expect the system to understand, say, USD1.5M as meaning "$1,500,000.00 US" and would expect to use that shorthand notation when entering payment details and to get the amount displayed the same way if they need to amend it later.

====

And yet, way back when having a PC with an 8086 in it was a sign of status, and PC financial programs where written in BASIC, the use of floating point for financial values was fairly common - but only because a 16 bit signed integer topped out at a mere GBP 327.68 OR were achingly slow because they had to use BCD or decimal encoded monetary values.

The Mainframes I've worked on have ALWAYS used integers for financial values, though quite a lot of the weedier bottom-of-the-range IBM boxes used BCD - but at least they had BCD hardware and didn't have to do calculations entirely in software.

--
--   
Martin    | martin at 
 Click to see the full signature
Reply to
Martin Gregorie

On Sat, 23 Jan 2021 22:54:30 -0000 (UTC), Martin Gregorie declaimed the following:

Even the old Intel 8080a had "BCD hardware" -- but one would have to write the algorithm to work with more than two BCD digits.

My college computer (Xerox Sigma-6) had BCD hardware. The normal mode used by the COBOL class was BCD (note: Sigma's also used the EBCDIC character encoding), 32-digit, using four of the 32-bit general purpose registers at a time. I recall the fall when the BCD board failed -- COBOL students were left twiddling their thumbs or trying to code work-arounds (possibly one of the COMP formats that did not use BCD), whereas the FORTRAN-IV students were not impacted. Think it took almost half the term before the BCD board was replaced.

--
	Wulfraed                 Dennis Lee Bieber         AF6VN 
	wlfraed@ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/
Reply to
Dennis Lee Bieber

For Financial derivative risk systems, it is still almost exclusively float(double) representation for money. The exponential function is frequently used in calculations and it works with doubles. Hence the added complexity of converting between doubles and decimals far outweighs any benefit.

BTW thank you for the awk idea the other day. If I whinge on about an idea for days, it means I like it. I'm a bit of a sperg when it comes to social graces.

Reply to
Pancho

which is ok until you need to do interest rate or currency conversion calculations

Or any investment in funds where there is a concept of a unit, but it can be bought in any decimal fraction...

--
WOKE is an acronym... Without Originality, Knowledge or Education.
Reply to
The Natural Philosopher

I first learnt Algol 60 on an Elliott 503 (huge grey boxes full of discrete transistor logic and ferrite core memory). Then I joined ICL from Uni, so all my mainframe time was on ICL 1900 and 2900 systems. All the 1900s used 24 bit word addresses, 6 bit characters (so needed shift codes to switch between caps and lower case) and, possibly a first for any manufacturer, a binary compiled on any machine in the range would run on all the rest). BCD was not part of their vocabulary, but every system could handle floating point though the small ones did it in firmware. I mostly programmed them in assembler and COBOL with some Algol68 a bit later.

Then I sort of wandered off onto 'small mainframes' (AS/400, now known as iSeries though they owed a huge amount to IBM's Future Series, which was canned around 1972 and then later revived as S/38 and then as AS/400) along with a bit of DEC stuff (VAX and Alpha), NCR servers and a lot of fault-tolerant kit (Tandem NonStop and Stratus systems). By then I was mostly writing C with side orders of SQL and TAL.

--
--   
Martin    | martin at 
 Click to see the full signature
Reply to
Martin Gregorie

Did the 8086 not have a BCD mode? I only ever dealt with 8086 assembly language for part of one semester in college.

The 6502 does BCD. I don't recall ever using it back in the day (wasn't writing much financial software when I was a kid), but I know it supported it. I just fired up an Apple II emulator and got the expected results:

0300 F8 SED 0301 18 CLC 0302 A9 15 LDA #$15 0304 69 27 ADC #$27 0306 8D 10 03 STA $0310 0309 D8 CLD 030A 60 RTS

Took a look in $0310 after running and it was set to $42, where it would've been $3C otherwise.

(Not that I've written much since that could be described as "financial software," but what I have written has used whatever fixed-point type was available.)

_/_ / v \ Scott Alfter (remove the obvious to send mail) (IIGS(

formatting link
Top-posting! \_^_/ >What's the most annoying thing on Usenet?

Reply to
Scott Alfter

Its not mentioned in the Wikipedia article: I'd expect a mention there if it could do BCD.

This isn't mentioned on its Wipedia article.

However, and more to the point, I don't think any of the 886 BASICs could do anything other than floating point and integer arithmetic - which is why most of the low-end financial packages for 8/16 bit microprocessors, which were typically written in BASIC, held monetary values in FP variables and were well-known for small financial inaccuracies as a result.

It looks as though you'd use BCD for monetary values in DBase II - I knew it existed but never used it.

The first (and last) 4GL I used was Sculptor, first on an SWTPC UniFlex system, then on PCs and finally on a OS9/68020 system. Sculptor stores monetary values as a 32 bit signed integer (so up to

+/- 21474836.48) and can store bigger values (up to 15 digits) as a floating point value. Monetary values are always represented externally with two digits after the decimal point, i.e. GBP, USD, EU, etc are all stored as binary pence or cents.
--
--   
Martin    | martin at 
 Click to see the full signature
Reply to
Martin Gregorie

I had "Business Basic" on my first computer based on the Z-80 processor and built from a kit made by Digital Group. It stored and did calculations in BCD. Any more details forgotten.

I still have the system, but haven't run it in maybe 35 years.

formatting link

formatting link

--
Jim H
Reply to
Jim H

It has instructions to adjust for BCD before or after the normal arithmetic operations.

--
https://www.greenend.org.uk/rjk/
Reply to
Richard Kettlewell

It was quite common to have a decimal adjust instruction in the early 8 bit microprocessors. The add was done in binary and then the decimal adjust instruction was used to "adjust" to valid BCD.

It started with the INTEL 4004 and continued onward 8051/52, 8080,

8086... The PIC processors had a similar DAW (decimal adjust W reg). Also variants in the Motorola 6800 family and the MOS Technology 6502.
Reply to
Dennis

On Mon, 25 Jan 2021 18:31:04 -0000 (UTC), Martin Gregorie declaimed the following:

formatting link
""" AAA ASCII adjust AL after addition used with unpacked binary coded decimal 0x37

AAD ASCII adjust AX before division 8086/8088 datasheet documents only base 10 version of the AAD instruction (opcode 0xD5 0x0A), but any other base will work. Later Intel's documentation has the generic form too. NEC V20 and V30 (and possibly other NEC V-series CPUs) always use base 10, and ignore the argument, causing a number of incompatibilities 0xD5

AAM ASCII adjust AX after multiplication Only base 10 version (Operand is 0xA) is documented, see notes for AAD 0xD4

AAS ASCII adjust AL after subtraction 0x3F """ """ DAA Decimal adjust AL after addition (used with packed binary coded decimal) 0x27

DAS Decimal adjust AL after subtraction 0x2F """

So... Not direct BCD operations, but use of regular integer register ops followed by an "adjust" operation to re-BCD the result.

--
	Wulfraed                 Dennis Lee Bieber         AF6VN 
	wlfraed@ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/
Reply to
Dennis Lee Bieber

It gets even worse than that. Microsoft BASIC (at least on the Apple II, though probably on other platforms as well) used floating-point for all math. You thought you were doing integer math by tacking "%" onto the variable name, but integer variables were converted to floating point for calculation and the result, if it was to go back to an integer variable, was converted back to integer. The only win was that they would've only needed two bytes to store instead of the six (I think) that floating-point variables needed.

Whether this carried over from 8-bit BASICs to 16-bit, I don't know. I kept using my Apple IIs well into the '90s. I built my first x86 system (a

12-MHz 286) back around '91 or '92 to run my BBS so I could have my Apple IIe back. By the time I started moving everyday computing tasks off the Apple II and onto x86 hardware, I was alternating between OS/2, Windows 95, and early versions of Linux.

_/_ / v \ Scott Alfter (remove the obvious to send mail) (IIGS(

formatting link
Top-posting! \_^_/ >What's the most annoying thing on Usenet?

Reply to
Scott Alfter

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.