While I’ve been buying goodies from https://gotek.nl, I missed a place to buy hard to find obscure items.
And then I found https://heinpragt.nl (Last year)
Awesome! Retro parts old and new, some are very hard to find!
While I’ve been buying goodies from https://gotek.nl, I missed a place to buy hard to find obscure items.
And then I found https://heinpragt.nl (Last year)
Awesome! Retro parts old and new, some are very hard to find!
Started working on my breadboard version of a 68k computer.
When it’s working, I’ll make a PCB version.
Using almost only parts I still have. (No 8mhz crystal)
The 68000 being 24 bit address and 16 bit data needs 2x 8-bit roms and 2x 8 bit ram, but i didn’t have the components yet in this picture.
While tinkering with above, my Fatter Agnus chip came in.
To make a 1mb chipmem version of your rev 5 amiga (PAL)
You need to have a newer version of the Agnus chip (I had 8371, and bought a 8372a) AND you need a 512kb trapdoor memory expansion.
An unmodded rev 5 will see 512kb Chip mem and 512 Fast mem.
Replacing the Agnus 8371 for 8372a:
I lost my PLCC puller, so I modded a paperclip into a puller 🙂


When placing the new chip, I had to tape pin 41 for PAL version.
I used Polyimide Film tape.
Next I had to cut the jumper 2 connection and solder the other pads.
(Bottom and middle disconnect and middle and top bridged)

Next was another cut on the PCB, this disables the trapdoor card detection.

Success!
I think we’ve seen Maderia .. 🙂
I bought a little notebook while being there.
I wrote about 12 pages of ideas, schematics and projects to start.

8085 Cartridge revisited
Problem with cartridge: prg is 17k, exomized 10k.
So you need 2 banks of 8k.
This disables basic rom, needed for the program.
The program needs to be relocated to 0x800 anyway.
So my exomizer options will take care of that.
But the basic is not being enabled again.
exomizer sfx sys -o data.exo -Di_ram_enter=\$37 -Di_ram_during=\$34 -f'LDA #$37 STA $01' 8085.prg xa frame.asm -o frame.bin x64 -cart16 frame.bin
Result … JAM
For my new SBC I’ll need a machine code build environment.
This is what I’ve setup now.
My main workstation is Linux based. While this setup is Linux based, vasm should work on other operating systems also.
Getting and compiling vasm for 68k
wget http://sun.hasenbraten.de/vasm/release/vasm.tar.gz tar xzvf vasm.tar.gz cd vasm # Building make CPU=m68k SYNTAX=oldstyle # Using ./vasmm68k_oldstyle -m68000 -Fbin -dotdir -no-opt source.asm # this generates a.out # Dumping the file (byte separated and with a offset of 0x8000) xxd -g 1 -o 0x8000 a.out | head 00008000: 30 3c aa aa 4e f9 00 00 80 04 00 00 00 00 00 00 0<..N........... 00008010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00008020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00008030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00008040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00008050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00008060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00008070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00008080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00008090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ # But my 68k needs an ODD EVEN eeprom # so I used another tool - romsplit git clone https://github.com/ullman/romsplit cd romsplit make all # Using romsplit ./romsplit -s a.out odd.rom even.rom # Split into 4? Split the splits using above # Output xxd -g 1 -o 0x8000 odd | head -1 ; xxd -g 1 -o 0x8000 even | head -1 00008000: 30 aa 4e 00 80 00 00 00 00 00 00 00 00 00 00 00 0.N............. 00008000: 3c aa f9 00 04 00 00 00 00 00 00 00 00 00 00 00 <............... # Burn these with minipro
Disassemble
m68k-linux-gnu-objdump --disassemble-all --target=binary --architecture=m68k a.out
68030 example for friend
# Compile vasm with make CPU=m68k SYNTAX=mot ------------ vasmm68k_mot -Fbin ./edk.asm ------------- .68030 ORG $0 ***** * exception table (256 x 4 bytes) ***** dc.l $400 ; Program Counter na reset (startadres) dc.l $20000 ; stackpointer (ram locatie) dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 org $400 ; hier starten move.l #$0,d0 loop1: add.l #$1,d0 cmp.l #$10000,d0 bne loop1 move.l #$0,d0 loop2: add.l #$1,d0 cmp.l #$10000,d0 bne loop2 nop nop nop ----- vasm 1.9f (c) in 2002-2023 Volker Barthelmann vasm M68k/CPU32/ColdFire cpu backend 2.6c (c) 2002-2023 Frank Wille vasm motorola syntax module 3.18 (c) 2002-2023 Frank Wille vasm binary output module 2.3a (c) 2002-2023 Volker Barthelmann and Frank Wille org0001:0(acrwx1): 0 bytes org0002:0(acrwx1): 1024 bytes org0003:400(acrwx2): 30 bytes ----- -rw-rw-r-- 1 henri henri 1054 aug 27 11:45 a.out
Test picture of a multiprocessor computer setup.
Using buttons on the right, I want the possibility to change between systems and keyboard settings.
Also, multiple software/OS slots for SDCards will be on the right.
The lid containing the keyboard has a handle!
After laser cutting a nice front, it could become a nice road warrior hacking station.
I’m going to replace the wireless keyboard, probably with a touch display and a programmable layout for keyboards.
Something like below
Some layouts:



I’ll probably buy this one from waveshare
Info about Faux86
yes, again. Another change.
UPDATE: Working example at bottom!
I don’t want IDs and Paths in a Home Assistant automation.
The RFIDs can store more than enough data to store the paths to albums.
I Also tested with ESPHOME in HA, but you can’t write tags.
ESPHOME Config for my RFID device (NOT USED ANYMORE)
esphome:
name: rfidtag
friendly_name: rfidtag
esp8266:
board: d1_mini
mqtt:
broker: IPMQTTBROKER
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "xxxxxxxxxxxxxxxxxx="
ota:
password: "xxxxxxxxxxxxxxxxxxxxx"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Rfidtag Fallback Hotspot"
password: "xxxxxxxxxxxxxx"
captive_portal:
spi:
clk_pin: D5
miso_pin: D6
mosi_pin: D7
rc522_spi:
cs_pin: D8
update_interval: 1s
on_tag:
then:
- mqtt.publish:
topic: rc522/tag
payload: !lambda 'return x;'
on_tag_removed:
then:
- mqtt.publish:
topic: rc522/tag_removed
payload: !lambda 'return x;'
The next iteration of my Rfid controller will have a write function for the RFID tags.


Not sure yet, also want to implement a wifi manager on the wemos.
Changes on above idea:
How does it work
RFid device is connected to the network.
Start query.py on your LMS server.
Search for an album name, it will present an ID and Album name in a list.
Enter the ID you want to program, or 0 to exit.
(This will also reset the programming mode)
Place an empty or previously programmed tag on the device.
It will write the album ID on the tag.
Then it will start the album.
Changing the tags will also just change the album playing.
(NOTE: My genre spotify player still works using this method, using the same device)
A second python script will read the Mqtt topic and control the Squeezebox player.
Python Code DB Query
import sqlite3
#paho-mqtt
import paho.mqtt.publish as publish
host = "IPMQTTBROKER"
port = 1883
topic = "spotify/rfid/in/write"
auth = {'username': 'xxxx','password': 'xxxxx'}
client_id = "spotithing"
def readSqliteTable(albumname):
try:
sqliteConnection = sqlite3.connect('/var/lib/squeezeboxserver/cache/library.db')
cursor = sqliteConnection.cursor()
albumname = "%" + albumname + "%"
cursor.execute("select * from albums where title Like ?",
(albumname,))
records = cursor.fetchall()
for row in records:
print("Id: ", row[0],row[1])
cursor.close()
except sqlite3.Error as error:
print("Failed to read data from sqlite table", error)
finally:
if sqliteConnection:
sqliteConnection.close()
album = input("Album name ? ")
readSqliteTable(album)
number = input("Enter ID or 0 to quit : ")
publish.single(topic, "00000" , qos=1, hostname=host, port=port,
auth=auth, client_id=client_id)
if number == 0:
exit()
publish.single(topic, number, qos=1, hostname=host, port=port,
auth=auth, client_id=client_id)
print("Program your tag")
print("Reset/disable writing using exit with 0!")
Python Code Controller (this one needs to be running at all times)
import paho.mqtt.client as mqtt
import urllib.request
def on_connect(client, userdata, flags, rc):
print("Connected with result code {0}".format(str(rc)))
client.subscribe("spotify/rfid/idlms")
def on_message(client, userdata, msg):
print("Message received-> " + msg.topic + " " + str(msg.payload)) # Print a received msg
urllib.request.urlopen("http://IPADDRESLMS:9000/anyurl?p0=playlistcontrol&p1=album_id:" + msg.payload.decode() + "&p2=cmd:load&player=b8:27:eb:11:16:ab")
#NOTE also change b8:27:eb:11:16:ab into you players MACAddress!
client = mqtt.Client("digi_mqtt_test")
client.on_connect = on_connect
client.on_message = on_message
client.connect('IPMQTTBROKER', 1883)
client.loop_forever()
Arduino Code (see schematic in other post)
#include <Arduino.h>
#include <SPI.h>
#include <MFRC522.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <PubSubClient.h>
#define SS_PIN 15
#define RST_PIN 0
MFRC522 mfrc522(SS_PIN, RST_PIN);
MFRC522::StatusCode status; //variable to get card status
byte buffer[18]; //data transfer buffer (16+2 bytes data+CRC)
byte size = sizeof(buffer);
uint8_t pageAddr = 0x06; //In this example we will write/read 16 bytes (page 6,7,8 and 9).
//Ultraligth mem = 16 pages. 4 bytes per page.
//Pages 0 to 4 are for special functions.
unsigned long cardId = 0;
WiFiClient net;
PubSubClient client(net);
const char* mqtt_server = "IPMQTTBROKER";
const char* ssid = "MYSSID";
const char* password = "MYSSIDPASS";
String topicStr = "";
byte buffer2[8];
boolean Rflag=false;
int r_len;
char payload[5];
byte value[5];
void setup() {
Serial.begin(9600);
SPI.begin();
mfrc522.PCD_Init();
WiFi.mode(WIFI_AP_STA);
WiFi.begin(ssid, password);
client.setServer(mqtt_server, 1883);
delay(100);
client.setCallback(callback);
delay(100);
client.subscribe("spotify/rfid/in/#");
}
void reconnect() {
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
}
while (!client.connected()) {
String clientId = "rfid-";
clientId += String(random(0xffff), HEX);
if (!client.connect(clientId.c_str(), "rfidclient", "...")) {
Serial.print("failed, rc=");
Serial.print(client.state());
delay(5000);
}
}
client.subscribe("spotify/rfid/in/#");
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print(F("Called"));
Rflag=true; //will use in main loop
r_len=length; //will use in main loop
Serial.print("length message received in callback= ");
Serial.println(length);
int j=0;
for (j;j<length;j++) {
buffer2[j]=payload[j];
}
if (r_len < 3) {
Rflag=false;
Serial.print(F("Set false"));
}
buffer2[j]='\0'; //terminate string
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
if (!mfrc522.PICC_IsNewCardPresent()) {
return;
}
if (!mfrc522.PICC_ReadCardSerial()) {
return;
}
if (Rflag) {
for (int i=0; i < 4; i++) {
//data is writen in blocks of 4 bytes (4 bytes per page)
status = (MFRC522::StatusCode) mfrc522.MIFARE_Ultralight_Write(pageAddr+i, &buffer2[i*4], 4);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Read() failed: (W) "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
}
Serial.println(F("MIFARE_Ultralight_Write() OK "));
Serial.println();
Rflag=false;
}
cardId = getCardId();
char buffer3[10];
sprintf(buffer3, "%lu", cardId);
client.publish("spotify/rfid/id", buffer3);
// Read data ***************************************************
Serial.println(F("Reading data ... "));
//data in 4 block is readed at once.
status = (MFRC522::StatusCode) mfrc522.MIFARE_Read(pageAddr, buffer, &size);
if (status != MFRC522::STATUS_OK) {
Serial.println(F("MIFARE_Read() failed: (R)"));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
Serial.println(F("Read data: "));
//Dump a byte array to Serial
for (byte i = 0; i < 5; i++) {
Serial.write(buffer[i]);
buffer2[i]=buffer[i];
}
client.publish("spotify/rfid/idlms", buffer,5);
delay(1000);
mfrc522.PICC_HaltA();
}
unsigned long getCardId() {
byte readCard[4];
for (int i = 0; i < 4; i++) {
readCard[i] = mfrc522.uid.uidByte[i];
}
return (unsigned long)readCard[0] << 24
| (unsigned long)readCard[1] << 16
| (unsigned long)readCard[2] << 8
| (unsigned long)readCard[3];
}
This week (while preparing for a mini retro party) I fixed some Amiga stuff.
I’ve bought a new gadget.
You place this PCB between the CPU IC socket and the CPU (68000) itself.

Now running a special floppy image, which loads a driver, I can use the 512MB sdcard as “harddisk”.
It at first ran into all kinds of hangups.
Checking everything, I found CIAB (8520) the culprit.
Timing errors I’ve never noticed before!
Switching this one with CIAA resolved the problem.
(I don’t use a printer anyway, but I have to remember that anything using the parallel port can have problems now.)



Meanwhile, I wanted to have a better control over the Amiga drives, so I’m planning to use a second switch to reassign drive numbers using a switch.
For switching Internal/External drive (df0/df1) I was using a Gotek boot switch. (Just press 3x ctrl-Amiga-Amiga)
See https://www.henriaanstoot.nl/2022/05/14/gotek-stuff/
But I have TWO external devices.
The Gotek virtual disk device and a real 5.24″ drive.
So I’m going to use a ON-ON double switch to toggle the external devices.



The internal switch toggles internal and external.
The secondary I’m going to build into the 5.25″ drive toggles df2 and the “df1”.
That way the internal drive can be 0 (boot) or 1.
The external drives can be 0,1 or 2.



NOTE: Switch pin 21 and 9 using the cross switch!
SO: Amiga with internal drive -> External 5.24″ which has a passthrough to the Gotek.
Another amiga thing fixed:
I re-installed Aros (on an old Laptop this time)


And third: I’ve bought the Amiga Forever cdrom.







When you get the ISO image from AmigaForever, and want to run it using Linux, do this to get it working
sudo apt install xkbfile1:i386
sudo apt install libxkbfile1:i386
mkdir -p /cdrom
sudo mount -t iso9660 ~/Downloads/AF.iso /cdrom
cd /cdrom/Private/Linux/e-uae/
./kxlight-start.sh
If you install Wine, you can use the windows gui in linux also.
Amiga samplers





Testing the sampler (demo for Tyrone)
Sampling the sound of a C64 on an Amiga.
Started (booted) the sampling program from second external drive using switch setup as above.
Yesterday I got this nice led matrix I mentioned before.
I wanted to control this display using Circuit Python and a Raspberry Pico.
Pico Matrix
GP0 R1
GP1 G1
GP2 B1
GP3 R2
GP4 G2
GP5 B2
GP6 A
GP7 B
GP8 C
GP9 D
GP10 Clock
GP11 E
GP12 Latch
GP13 Output Enable
GND GND ( I did both )
I installed Circuit Python and the following libraries.
adafruit_imageload, adafruit_display_text.label (the rest was already in the uf2 firmware.)
(Check this link : https://circuitpython.org/board/raspberry_pi_pico/ )
I could not install the Wifi uf2 file, then I got a out of storage space when installing the adafruit libraries.
importing libaries and init display
import board, digitalio, busio, time, displayio, rgbmatrix, framebufferio
import adafruit_imageload, terminalio, random
import adafruit_display_text.label
displayio.release_displays()
matrix = rgbmatrix.RGBMatrix(
width=64, bit_depth=2, height=64,
rgb_pins=[board.GP0, board.GP1, board.GP2, board.GP3, board.GP4, board.GP5],
addr_pins=[board.GP6, board.GP7, board.GP8, board.GP9, board.GP11],
clock_pin=board.GP10, latch_pin=board.GP12, output_enable_pin=board.GP13)
display = framebufferio.FramebufferDisplay(matrix)
I became interested in Conway’s “Game of Life”, in 1983. Reading a article in the Dutch Magazine Kijk.
The Game of Life, also known simply as Life, is a cellular automaton devised by the British mathematician John Horton Conway in 1970. It is a zero-player game, meaning that its evolution is determined by its initial state, requiring no further input. One interacts with the Game of Life by creating an initial configuration and observing how it evolves. It is Turing complete and can simulate a universal constructor or any other Turing machine.
https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
I found these on my server. Bad quality, I know. Scanned these many years ago.



The rules are:
When playing with the Basic code as a kid, I wanted to try if it was possible to make a 3D version of this.
I came up with the following rules:
I think there should be a BBC Acorn basic version I wrote somewhere.
Back to the display



Code for the glider gun
conway_data = [
b' + ',
b' + + ',
b' ++ ++ ++',
b' + + ++ ++',
b'++ + + ++ ',
b'++ + + ++ + + ',
b' + + + ',
b' + + ',
b' ++ ',
]
Next todo:
A long time ago I had an Action Replay II.
I modded it and was planning to rebuild this using pluggable eurocard-prints.
Then it got lost, somewhere.
Today I went to Almelo with Tyrone.
In the morning reverse engineering a lift controller print, and afternoon going to a guy selling a lot of Retro stuff.
And there it was, an Action Replay II for Amiga just catching dust.
I had to buy it, and got a sh*tload of 27256 Eproms for free!











This version is compatible with the A500/A1000 version only. It also plugs into the side expansion port. It introduces the following features:
A special A2000 version is available for this particular revision. Instead of plugging into the side expansion port it plugs into the 86 pin CPU slot.
Soldering almost done, except for the space bar all tactile buttons in place.


Using my USBasp programmer I tried to program the Atmega328pb.
Same one I used for:
I first needed to implement some udev rules to get the rights for the reader correct.
#/etc/udev/rules.d/99-usbasp.rules
SUBSYSTEM=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05dc", GROUP="dialout"
Next I tried to burn a bootloader.
Well, not as planned, back to the drawing board.
Hopefully I compiled at least the Pico part correctly.