Tag Archives: hardware

Computer cards i’ve owned / used

Only cards worth mentioning.
I will add more information to this page

Graphics:

Hercules ???? – Did a lot of machinecode on this one. (Which?)
CGA/EGA Card ??? – Machinecode hacking
VGA .. first card also machine code hacking
Matrox
Some cards i knew a lot about, i did some manipulations using assembly that were very interesting, but only worked on that specific brand.

16 Bit ISA VGA card that is compatibe with 8bits slots for my XT.
see https://www.henriaanstoot.nl/2022/11/16/hercules-to-vga/

Sound:

I’ve bought a lot of Crystal Soundcards, there were breeze to install and use under linux, way back when it was hard to get supported hardware.



Firewire card (for Studio equipment):

Our old trusty mixer

Videocapture:

Video blaster – Which i used to record video (Like ‘Sepp en fash vervelen zich nooit’) and my DIY controllable webcam.

Video Blaster


Pinnacle PCTV- Brooktree Bt848

I used the firewire connection to get the footage of my Canon Video Camera

Firewire cable
Not my card but comparable


Hauppauge WinTV PVR 350


Basetech BR116 (Current) – RCA

Not really a “card”


Camlink 4K (Current) – hdmi

Other:

Stallion RS-232 card for connecting multiple serial terminals.
(Icecrew chat server on Lan Parties)

insmod istallion board0=brumby,0x350,0xcc000
/usr/lib/stallion/stlload -i 2681.sys


Wyse Multiport Serial Card

Ramvantage 16bits ISA memory expansion

PC Hardware diagnostics card

Could not find any information on this card

Catweasel

The Catweasel is a family of enhanced floppy-disk controllers from German company Individual Computers. These controllers are designed to allow more recent computers, such as PCs, to access a wide variety of older or non-native disk formats using standard floppy drives.

You could connect joysticks and there is a socket for a SID chip on the card.

Servo’s Rotary encoders, Node-red and Mqtt

Multiple rotary encoders are controlling a servo based lock. 3 players have to work together to open the lock.

Secure MQTT rotary encoder (Can be used over the internet)
Servo based lock
Lock Mockup
Node red test logic

Arduino Rotary button (mqtt)

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <time.h>
#include <PubSubClient.h>

#define encoderCLK 5   //D1
#define encoderDT 4    //D2
int servoAngle = 0;
int crntCLK;
int prvsCLK;
String myString;
char ang[50];

#ifndef SECRET
const char ssid[] = "MYSSID";
const char pass[] = "MSSIDPASS";

#define HOSTNAME "rotary1"

const char MQTT_HOST[] = "securemqttserver";
const int MQTT_PORT = 8883;
const char MQTT_USER[] = "user"; // leave blank if no credentials used
const char MQTT_PASS[] = "pass"; // leave blank if no credentials used

const char MQTT_SUB_TOPIC[] = "escape/" HOSTNAME "/in";
const char MQTT_PUB_TOPIC[] = "escape/" HOSTNAME "/out";
const char MQTT_PUB_TOPIC_angle[] = "escape/" HOSTNAME "/angle";

#ifdef CHECK_CA_ROOT
static const char digicert[] PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
MIIFtTCCA52gAwIBAgIUXEEQRLHhYox8a95YiAYX/wQ/XeMwDQYJKoZIhvcNAQEN
----8< snip snap
CyLjTT2rtllw==
-----END CERTIFICATE-----
)EOF";
    #endif

    #ifdef CHECK_PUB_KEY
    // Extracted by: openssl x509 -pubkey -noout -in ca.crt
    static const char pubkey[] PROGMEM = R"KEY(
    -----BEGIN PUBLIC KEY-----
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    xxxxxxxx
    -----END PUBLIC KEY-----
    )KEY";
    #endif

    #ifdef CHECK_FINGERPRINT
	// Extracted by: openssl x509 -fingerprint -in ca.crt
    static const char fp[] PROGMEM = "AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD";
    #endif
#endif

//////////////////////////////////////////////////////

#if (defined(CHECK_PUB_KEY) and defined(CHECK_CA_ROOT)) or (defined(CHECK_PUB_KEY) and defined(CHECK_FINGERPRINT)) or (defined(CHECK_FINGERPRINT) and defined(CHECK_CA_ROOT)) or (defined(CHECK_PUB_KEY) and defined(CHECK_CA_ROOT) and defined(CHECK_FINGERPRINT))
  #error "cant have both CHECK_CA_ROOT and CHECK_PUB_KEY enabled"
#endif

BearSSL::WiFiClientSecure net;
PubSubClient client(net);

time_t now;
unsigned long lastMillis = 0;

void mqtt_connect()
{
  while (!client.connected()) {
    Serial.print("Time: ");
    Serial.print(ctime(&now));
    Serial.print("MQTT connecting ... ");
    if (client.connect(HOSTNAME, MQTT_USER, MQTT_PASS)) {
      Serial.println("connected.");
      client.subscribe(MQTT_SUB_TOPIC);
    } else {
      Serial.print("failed, status code =");
      Serial.print(client.state());
      Serial.println(". Try again in 5 seconds.");
      /* Wait 5 seconds before retrying */
      delay(5000);
    }
  }
}

void receivedCallback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Received [");
  Serial.print(topic);
  Serial.print("]: ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
}

void setup()
{
  pinMode (encoderCLK,INPUT_PULLUP);
  pinMode (encoderDT,INPUT_PULLUP);
  prvsCLK = digitalRead(encoderCLK);
  Serial.begin(115200);
  Serial.println();
  Serial.println();
  Serial.print("Attempting to connect to SSID: ");
  Serial.print(ssid);
  WiFi.hostname(HOSTNAME);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(1000);
  }
  Serial.println("connected!");

  Serial.print("Setting time using SNTP");
  configTime(1 * 3600, 0, "pool.ntp.org", "time.nist.gov");
  now = time(nullptr);
  while (now < 1510592825) {
    delay(500);
    Serial.print(".");
    now = time(nullptr);
  }
  Serial.println("done!");
  struct tm timeinfo;
  gmtime_r(&now, &timeinfo);
  Serial.print("Current time: ");
  Serial.print(asctime(&timeinfo));

  #ifdef CHECK_CA_ROOT
    BearSSL::X509List cert(digicert);
    net.setTrustAnchors(&cert);
  #endif
  #ifdef CHECK_PUB_KEY
    BearSSL::PublicKey key(pubkey);
    net.setKnownKey(&key);
  #endif
  #ifdef CHECK_FINGERPRINT
    net.setFingerprint(fp);
  #endif
  #if (!defined(CHECK_PUB_KEY) and !defined(CHECK_CA_ROOT) and !defined(CHECK_FINGERPRINT))
    net.setInsecure();
  #endif

  client.setServer(MQTT_HOST, MQTT_PORT);
  client.setCallback(receivedCallback);
  mqtt_connect();
}

void loop()
{
   crntCLK = digitalRead(encoderCLK);

 if (crntCLK != prvsCLK){
      // If the encoderDT state is different than the encoderCLK state then the rotary encoder is rotating counterclockwise
        if (digitalRead(encoderDT) != crntCLK) {
          servoAngle ++;

        }
        else {
          servoAngle --;
         }
         Serial.println(servoAngle);
          String myString = String(servoAngle);
          myString.toCharArray(ang, myString.length() + 1);
          client.publish(MQTT_PUB_TOPIC_angle, ang, false);
 }
  prvsCLK = crntCLK; 
  
  now = time(nullptr);
  if (WiFi.status() != WL_CONNECTED)
  {
    Serial.print("Checking wifi");
    while (WiFi.waitForConnectResult() != WL_CONNECTED)
    {
      WiFi.begin(ssid, pass);
      Serial.print(".");
      delay(10);
    }
    Serial.println("connected");
  }
  else
  {
    if (!client.connected())
    {
      mqtt_connect();
    }
    else
    {
      client.loop();
    }
  }

  if (millis() - lastMillis > 5000) {
    lastMillis = millis();
    client.publish(MQTT_PUB_TOPIC, ctime(&now), false);
  }
}

Arduino 3 servos using mqtt

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Servo.h> 
Servo lock1; 
Servo lock2;
Servo lock3;

const char* ssid = "MYSSID";                // WiFi SSID
const char* password = "MYSSIDPASS";        // WiFi Password
const char* mqtt_server = "MQTTSERVER";  // IP Broker MQTT
const char* topic_lock1 = "escape/servo/lock1";
const char* topic_lock2 = "escape/servo/lock2";
const char* topic_lock3 = "escape/servo/lock3";
 
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

void setup() {

  Serial.begin(115200);
  lock1.attach(D1);
  lock2.attach(D2);
  lock3.attach(D3);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
 String string;
 Serial.print("Message arrived [");
 Serial.print(topic);
 Serial.print("] ");
 for (int i = 0; i < length; i++) {
 string+=((char)payload[i]); 
 }
 Serial.print(string);
 Serial.print(" toInt ");
 int pos = string.toInt(); 
 Serial.println(pos);

 
 if ( strcmp(topic, topic_lock1) == 0 ) {
 Serial.print("lock1 ");
 Serial.println(pos);
 lock1.write(pos); 
 }
 if ( strcmp(topic, topic_lock2) == 0 ) {
 Serial.print("lock2 ");
 Serial.println(pos);
 lock2.write(pos); 
 }
 if ( strcmp(topic, topic_lock3) == 0 ) {
 Serial.print("lock3 ");
 Serial.println(pos);
 lock3.write(pos); 
 }
 
 delay(15); 
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("ESP8266servolocks")) {
      Serial.println("connected");
      client.subscribe(topic_lock1); 
      client.subscribe(topic_lock2); 
      client.subscribe(topic_lock3); 
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}
void loop() {   
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  delay(100);
}

Connect the wires puzzle

As part of my internet based escape room.

I took the idea from the Keep-talking-and-nobody-explodes game.

When starting up, is gets the configuration from a Mqtt Topic.
So i can create a different setup over the internet.

The result is also send back via MQTT.

(example play, all players are on different locations)

  • Player 1 figures out the wires.
  • Player 2 connects the wires.
  • Player 3 sees the result (correct or not) and next puzzle opens up for Player 3

I used a wire with a line. Multiple colors for jacks and sockets.
It’s also possible to connect a jack to a jack.
Loads of possibilities.

Todo:

Wifi and Mqtt part
Debounce software or hardware

Arduino Concertina

Lets try to make a Electronic Concertina

UPDATE:
https://www.henriaanstoot.nl/2023/01/10/arduino-concertina-poc/
https://www.henriaanstoot.nl/2023/01/17/arduino-concertina-poc-2/

First design

So we need some pushbuttons … at least 14 .. for the most simple tunes.
A sensor for push and pull.
A buzzer or better yet .. a jack for earphones.
Arduino with enough pins to connect a keyboard matrix.
When using a keyboard matrix only single keypresses are detected.
So we cant do chords!

Raspberry Zero with display

I’ve installed a headless Raspbian on a Pi Zero with a 2×16 Chars lcd display. As part of the Escape Room over the internet

Using the raspberry imager:
I’ve set the username/password and ssh access in this tool.
For wifi access i’ve placed below file on the SDcard in /boot
(You can do this in the tool, but i want to make this dynamic when connected at a remote site.)
file: wpa_supplicant.conf

country=NL
update_config=1
ctrl_interface=/var/run/wpa_supplicant

network={
 scan_ssid=1
 ssid="MYSSID"
 psk="MYSSIDPASS"
}

ssh into the RPi

sudo raspi-config
Interface options and enable I2C

sudo apt-get install python3-smbus

wget https://gist.githubusercontent.com/DenisFromHR/cc863375a6e19dce359d/raw/36b82e787450d127f5019a40e0a55b08bd43435a/RPi_I2C_driver.py
and 
wget https://gist.githubusercontent.com/DenisFromHR/cc863375a6e19dce359d/raw/36b82e787450d127f5019a40e0a55b08bd43435a/examples.py

For python3 edit the example and put at the top

# requires RPi_I2C_driver.py
import RPi_I2C_driver
from time import *
unichr = chr

Run with 
python3 examples.py
lcd display with i2c backpack
I2C backpack

Below is a mockup session.

Next todo:

  • Add more hardware (like buttons) to the RPI
  • Configure an Accesspoint on this Rpi for other devices to connect to
  • Install a local Mqtt broker, which connects secure to my internet facing broker
Setup example

Serial link between MSDos and Linux troubles

In post https://www.henriaanstoot.nl/2022/11/25/disk-troubles-or-missing-old-skool-hardware/ i mentioned the serial connectors i’ve bought to connect the Laser XT to my Workstation to transfer files.

The null modem i’ve made is like mentioned on https://en.wikipedia.org/wiki/Null_modem

I’ve used the loopback handshaking using 3 wires. ( Only using a DB25 and a DB9 on the other end )

So i configured the Linux side as follows.

I’ve tried two usb to serial converters.

Both when trying on windows 10 are not supported any more

Dec 14 17:34:40 zspot kernel: [ 1082.299607] usb 1-4: pl2303 converter now attached to ttyUSB0

sudo stty -F /dev/ttyUSB0 9600

Then i start dosbox.
To enable a com port i have to enter:

serial1=directserial realport:ttyUSB0

Starting Norton Commander and selecting COM1

After a few seconds i got this ..

What else is there to check?
At least i’ve still got the Flux Engine!

Fluxengine disk reader

I’ve build a drawbridge disk reader in the past:
https://www.henriaanstoot.nl/2022/04/26/started-to-build-a-drawbridge/
I found an even more interesting project.

I was looking for a solution to my XT laser problem.
https://www.henriaanstoot.nl/2022/11/25/disk-troubles-or-missing-old-skool-hardware/

And found this! The fluxengine
https://github.com/davidgiven/fluxengine

An open source project using a small controller board.
“Flashing” some software on the board and soldering a pinheader was easy.
When connecting a flat cable and a floppy drive, you end up with a device which can read many formats. Including dos 1.44/720 and amiga.

Nice package it came in

Using the power from a sata/ide harddisk adaptor

Reading and writing a MSDOS disk, no problem.
Imaging an amiga disk .. easy!

You need to compile some software, but it was well documented

Disk troubles or missing old skool hardware?

I bought a XT Laser/3 a while ago.
And i wanted to get my old programs running on it again.

One of the disk i found was a 5.25 inch boot disk which should contain a boot demo i’ve made in the past with Edk.
But it is the secondary drive in this system. Those old machines lack a bios you can change.
And change A: for B: for example.
Some machines had a program which could alter boot settings. (not this one)
So i was playing with jumpers and dipswitches on the motherboard.
( Drive select / Termination / drive before or after the twist in the flatcable. )

Dipswitches on the motherboard

Wellll leave the boot order for now, i needed to get software on the machine using floppy’s.
I could not find empty HD disks (1.44MB which i wanted to use)
So i took a DD disk and a drill ..

(Image from the internet)

I bought an external usb floppy drive.

Now i have everything to get my programs on the msdos machine.

EXCEPT ….

Diskette didn’t work in the drives.
So i bought new old stock diskettes online.

Now i have everything

WRONG again

Formatted 1.44 disk in USBfloppy drive .. OK
Read in 3.5 drive on the MSDOS machine .. NOT OK
Check drive in MSDOS machine .. is 1.44MB .. OK
… check floppy controller in MSDOS machine .. NOT OKAY
(720kb is 300kbits per second and 1.44 HD 500kbits per second)
So i’m limited to 720kb due to the controller ..


Can the USB Floppy drive read/write 720kb disks .. NO!
( A cheap series made with drives only supporting HD disks )

Alternatives? .. Serial maybe, there is Norton Commander on the MSDOS machine so i could use “link”

Do i still have a USB-RS232 sub-d cable ? YES!
Nullmodem cable? NO
Make a null modem cable .. i’ve made those before .. BUT no sub-d connectors.

I’ve been throwing away too much in the past.

Now i have to buy those things again:

VGA – 8bit ISA – have 2 now
Floppy drive – have one for 1.44
8bit soundblaster compatible – TODO
Nullmodem – well i’ve bought connectors for those

Hercules to VGA

While playing with MuseScore….
(Typesetting some scores for Pipes and Flute)

This came in: WOOOT

Trident 8900C (1024 x768 max 512Kb)

This is a Trident VGA card. While having a 16bit ISA connector, it can work in a 8bits ISA slot.

A while ago i bought a Laser XT/3, that’s the one my parents had.
This is where i did a lot of assembly programming on.
It’s a 8086 cpu, 640K and has a Hercules/CGA graphics card.

I found loads of assembly files and i want to see if i can get it running again.
While some code was written for hercules, ( That’s the monochrome image you see in the example above ) and a few for EGA (4 colors).

Most of it was written for VGA. Probably on a later machine like a 80386?

But i know there are vga cards for 8 bit msdos computers, and i found one. ( This one is even autodetect, so no jumpers to figure out)

So i’ve put this card in the machine, turned it on, and it works!
I’ve got only 2 examples living on the harddisk of the machine, both black and white … 🙂
I have to search for interesting code in hundreds of files.

Some friends of mine, picture was taken from an amiga genlock digitizer
The intro pages of a “amiga emulator” WHERE is the rest??? (end is a cga starfield demo)

Hercules Card

There is not much info available about this card:

  • Max resolution (Hercules) : 720×348
  • 15 pin analog monitor port (CN1)
  • BIOS enabled JP1 Pins 1 & 2 closed
  • BIOS disabled JP1 Pins 2 & 3 closed
  • CGA selected SW1 On
  • MDA (Hercules) selected SW1 Off

Floppy drive boot

My friend EDK and I made some demo’s like

And a boot demo, which was able to start from a bootsector, went into a graphic mode and ran a demo with sound. Edk wrote a sector loader for this.
I have some 5.25 inch floppy disks, labelled boot demo. So i wanted to try this today …
I needed to change the boot order, so i went online to search for jumper settings.

I see a led when it tries to boot, but my disks are probably formatted 720Kb instead of 360Kb, which this drive is.

So …. TODO!

Find a 720Kb floppy drive (5.25 inch), and sort through my code!
There is a 8bit soundblaster compatible soundcard that i bidding on online, hopefully i’ll get it

Assembly and modes

I wasn’t sure how to sort the assembly code into Hercules and VGA compatible, but i used this table (There are also extended modes for higher resolutions)

mode 0x00text 40×25 gray
mode 0x01text 40×25 16 colors
mode 0x02text 80×25
mode 0x03text 80×25 16 color
mode 0x04graphics mode (CGA) 320×200
mode 0x05graphics mode (CGA) 320×200
mode 0x06graphics mode (CGA) 640×200 (B/W)
mode 0x07text 80×25 Hercules
mode 0x0Fgraphics mode 640×350? gray
mode 0x10graphics mode 640×350?
mode 0x11graphics vga 2 colors
mode 0x12graphics vga 16 colors
mode 0x13graphics 320×200 256 colors
# Set VGA mode
    mov ax,13h
    int 10h         ;screen 320x200 256 colours

# Exit VGA mode
    mov ax,3
    int 10h         ;screen  80x25 text
    mov ax,4c00h
    int 21h         ;back to DOS