Rather than the bespoke setup described in the article, I guess the most-common equivalent these days is a USB connection to a Raspberry Pi or Arduino or similar?
Rather than the bespoke setup described in the article, I guess the most-common equivalent these days is a USB connection to a Raspberry Pi or Arduino or similar?
Also the MIDI-game port which was basically an ADC for the PC, meaning you could build your own gaming racing steering wheel using a volume knob screwed in the middle of a CD cake case and pedals using volume wipers, all connected to the MIDI port with no extra drivers needed. Good times.
Er, what? Not every IBM PC (clone) had a (sound) card with joystick ports, but almost every PC clone had (ISA, later PCI) extension slots. There were/are plenty of digital i/o adapter cards for those available, from plain, cheap 8255 based ones to those with slave CPUs (potentially more powerful than the host's CPU).
But then, perhaps I don't understand what you mean by 'intentional' GPIO.
If you didn't care about burning CPU, you could bit bang these "button" inputs and interface simple home-brew electronics. The clock line attaches to one "button" pin, the data line attaches to another "button" pin. When button 1 is "pressed" sample the state of button 2! Now you are reading a data stream.
I used this trick to interface magstripe readers directly to computers back in the early 2000s, and even wrote an article for the first issue of O'Reilly's Make Magazine about it. While professional readers/writers were hard to get, cost $100+, interfaced to the parallel or serial port, and used proprietary software, this let me do it for around ~$20 in parts and use my own software. I had quite a lot of fun learning what was stored on the various tracks of the cards I had, like my student id.
https://stripesnoop.sourceforge.net
Fun times of directly accessing hardware.
Back in the day parallel ports were awesome because they were effectively 8 serial ports in parallel (sounds awesome right? 8 times the bandwidth)
But then some dude came along and USB did 100X the bandwidth in a serial bus. Then other dudes were like "okay great now let's put multiple USB data pairs in parallel" and boom USB 3.2 was born. Parallel again. USB-C is effectively a UPB.
Parallel ATA was the shit back in the day for hard drives but then Serial ATA replaced it. Now we're at NVMe which is parallel again with 4 PCIe lanes.
CompactFlash (parallel) -> SD (serial) -> UHS-II (parallel), same story
BNC cable ethernet (serial) -> 100-Base-TX (parallel) -> fiber (serial) -> fiber bundles (parallel), same story
The difference is all the bits in a true parallel interface operate synchronously. All the bits get set; the clock pulses to signal data is ready; all the bits update again. The problem with this approach is you have to wait for all the bits to settle before you can read. It's no problem at low frequencies, but when you get into hundreds of MHz or more, it becomes a real challenge to get everything time-aligned.
4xPCIe channels operate on 4 independent clocks. They have the same nominal rate, but they don't have to be precisely aligned. Each channel is transmitting a single frame at a time - it's not splitting them into 4-bit packets and sending 1 bit down each channel.
I'm hard-pressed to think of a new technology in the last decade that implements splitting a byte into bits and sending each down a separate line.
In the mid to late 90s, I was sharing my main 486's dial-up connection with an old clunky laptop using PLIP:
https://docs.kernel.org/networking/plip.html
So my brother and I could both use Netscape at the same time, on two different computers. Felt like the future!
P.S: actually the laptop was just running an X (back then not even Xorg yet) and displaying a Netscape window running on the main, beefier, PC. All over PLIP : )
https://en.wikipedia.org/wiki/List_of_DOS_commands#INTERSVR_...
https://www.adafruit.com/product/2264
https://ftdichip.com/products/ft2232h-mini-module/
Bit banging on a modern OS subjects you to a lot of jitter though. It's not like using a parallel port in DOS where you just have to worry about interrupts. The preemptive scheduler can really mess up your timing.
That said, the FT232H, FT2232H, and FT4232H have an FTDI Multi-Protocol Synchronous Serial Engine (MPSSE) cores that you can program to protocols like SPI and I2C where the high speed part doesn't require any smart logic to handle. It's a bit of a special skill though (you send MPSSE specific command bytes over the USB interface into the chip's command buffer and tell it to execute them).
If you need more high speed smarts, it's also convenient to use a Raspberry Pi Pico with MicroPython or CircuitPython with Programmable I/O (Pio) with an interactive session:
https://www.raspberrypi.com/news/what-is-pio/
https://docs.micropython.org/en/latest/rp2/quickref.html#pro...
But yeah, beyond that, you're better off using an Arduino or something and doing it all on the microcontroller.
On the plus side, all of these things are relatively cheap and easy to obtain.
http://developer.intra2net.com/git/?p=libftdi;a=blob;f=examp...
It's dead simple to also use these FTDI devices with Python:
I can't believe I'm not missing something... Is there an off the shelf USB GPIO device somewhere? Plug it in and start using the linux GPIO driver?
The solution my friends gave me was "buy an arduino", flash the arduino, and use the arduino's gpio... which yeah, I could do, but is that really what it takes for a $2000 desktop to flip a bit these days?
https://www.adafruit.com/product/2264 - USB to GPIO (and other stuff)
"Bus Pirate"
Or get a RasPi - it's not your desktop PC, but they're running Linux with direct GPIO access available in userspace.
See page 9 of the datasheet here:
https://ftdichip.com/wp-content/uploads/2020/07/DS_FT232H.pd...
The async and sync bitbang columns denote the GPIO pins as D0-D7 and show them assigned to the 8 ADBUS pins that are provided on the breakout board.
Assuming the udev rules are set up in Linux, you can simply install pyftdi, open the device, and start using the ADBUS pins as GPIO pins:
https://eblot.github.io/pyftdi/gpio.html#setting-gpio-pin-st...
If you're using libftdi, you want to call ftdi_set_bitmode with the BITMODE_BITBANG enum value for the mode:
https://www.intra2net.com/en/developer/libftdi/documentation...
Then the ftdi_read_data and ftdi_write_data functions can be used to read or write to the ADBUS pins:
https://www.intra2net.com/en/developer/libftdi/documentation...
https://www.intra2net.com/en/developer/libftdi/documentation...
You can then build a nice, simple high level GPIO interface over that if you want.
R-2R Soundcard!
Soundblasters were crazily expensive (and a Gravis UltraSound even more), but you could solder a R-2R resistor ladder [1] connected to the parallel port, and have pretty decent soundcard (well, at least when compared to the onboard speaker) for $10 or less [2].
Not many games worked with it, but it was quite popular amongst the demoscene at the time.