View source | |
# 2025-07-19 - OCC BasLinux, Slackware 4.0, And Flip-Card | |
I am a fan of using a Linux live system as a runtime and Slackware | |
as a development environment for it. Slack15 Puppy Linux can | |
install Slackware 15.0 packages. Slacko Puppy Linux can install | |
Slackware 14.2 packages. | |
What i am writing about today is BasLinux, a live system that runs | |
Linux from a 1.44 MB floppy. A second 1.44 MB floppy gives X11. | |
It runs Linux kernel 2.2, busybox, and it is based on Slackware 4.0. | |
This means that you can build programs in Slackware 4.0 and run them | |
on BasLinux. This also means that BasLinux is limited to | |
"period hardware". | |
I appreciate the little conveniences in Alpine Linux. For example | |
the `losetup -P` option scans a loopback device for partitions, | |
eliminating the need for kpartx from multipath-tools. | |
# Install Qemu | |
iris:~# apk add qemu-system-i386 qemu-ui-sdl | |
# Install Slackware 4.0 On Development VM | |
Download the Slackware 4.0 ISO images plus any desired patches. | |
In my opinion Slackware 4.0 has aged well compared to other | |
distributions of its era. | |
Slackware 4.0 ISO images | |
Slackware 4.0 mirror (FTP) | |
Slackware 4.0 mirror (gopher) | |
Make a Qemu startup script. 16 MB RAM should be plenty. | |
iris:~$ mkdir -p Qemu/slack40 | |
iris:~$ cd Qemu/slack40 | |
iris:~/Qemu/slack40$ truncate -s 500M slack40.raw | |
iris:~/Qemu/slack40$ cd | |
iris:~$ cat >qemu-slack40.sh <<'__EOF__' | |
#!/bin/sh | |
DISK="/home/ben/Qemu/slack40/slack40.raw" | |
BASE="Slackware Linux 4.0 (Walnut Creek) (June 1999)" | |
CDROM="/home/ben/Downloads/${BASE} (Disc 1).iso" | |
MACH="pc-i440fx-9.2,dump-guest-core=off,mem-merge=off,usb=off" | |
SAND="on,obsolete=deny,elevateprivileges=deny,spawn=deny" | |
SAND="${SAND},resourcecontrol=deny" | |
qemu-system-i386 \ | |
-accel kvm \ | |
-machine "$MACH" \ | |
-overcommit mem-lock=off \ | |
-no-user-config \ | |
-sandbox "$SAND" \ | |
-msg timestamp=on \ | |
-cpu max \ | |
-m 16M \ | |
-global i8042.kbd-throttle=on \ | |
-device VGA \ | |
-hda "$DISK" \ | |
-cdrom "$CDROM" \ | |
-display sdl,gl=off,grab-mod=rctrl \ | |
-rtc base=localtime | |
__EOF__ | |
iris:~$ chmod a+rx qemu-slack40.sh | |
iris:~$ ./qemu-slack40.sh | |
This will boot the Slackware 4.0 install media. | |
At the boot: prompt, press Enter. | |
At slackware login:, type: root | |
Press Enter | |
Partition the disk. | |
# fdisk /dev/hda | |
... | |
Command (m for help): o | |
... | |
Command (m for help): n | |
Command action | |
e extended | |
p primary partition (1-4) | |
p | |
Partition number (1-4): 1 | |
First cylinder (1-1015, default 1): 1 | |
Last cylinder or +size ... (1-1015, default 1015): 1015 | |
Command (m for help): a | |
Partition number (1-4): 1 | |
Command (m for help): w | |
Calling ioctl() to re-read partition table. | |
hda: hda1 | |
hda: hda1 | |
Syncing disks. | |
WARNING: If you have created or modified any DOS 6.x | |
partitions, please see the fdisk manual page for additional | |
information. | |
Start the Slackware installer. | |
# setup | |
Select TARGET and press Enter | |
Please select a partition from the following list to use for your | |
root (/) Linux partition. | |
Select /dev/hda1 and press Enter | |
Select Format and press Enter | |
Select 4096 1 inode per 4096 bytes. (default) and press Enter | |
Wait for it to format the filesystem. | |
At DONE ADDING LINUX PARTITIONS TO /etc/fstab, Press Enter to EXIT | |
At CONTINUE?, select Yes and press Enter | |
At SOURCE MEDIA SELECTION: | |
Select 1 Install from a Slackware CD-ROM | |
Press Enter | |
At CHOOSE INSTALLATION TYPE, select slakware and press Enter | |
At CONTINUE?, select Yes and press Enter | |
At PACKAGE SERIES SELECTION: | |
Use arrow keys and space | |
Clear box next to E GNU Emacs | |
Clear box next to F FAQ lists, HOWTO documentation | |
Clear box next to T TeX typesetting software | |
Clear box next to XAP X Applications | |
Clear box next to XV XView (OpenLook Window Manager, apps) | |
Clear box next to Y Games (that do not require X) | |
Select OK and press Enter | |
At CONTINUE?, select Yes and press Enter | |
At SELECT PROMPTING MODE, select full and press Enter | |
Wait for slackware installer to complete | |
At MAKE BOOTDISK, select continue and press Enter | |
At MODEM CONFIGURATION, select no modem and press Enter | |
At SCREEN FONT CONFIGURATION, select No and press Enter | |
At INSTALL LILO, select simple and press Enter | |
At SELECT LILO DESTINATION, select MBR and press Enter | |
At CONFIGURE NETWORK?, select No and press Enter | |
At MOUSE CONFIGURATION, select ps2 and press Enter | |
At GPM CONFIGURATION select No and press Enter | |
At SENDMAIL Configuration, select Cancel and press Enter | |
At TIMEZONE Configuration, select US/Pacific and press Enter | |
At set a root password? select Yes and press Enter | |
At New password: enter root password and press Enter | |
At Re-enter new password: enter root password again and press Enter | |
At Press [enter] to continue: press Enter | |
At SETUP COMPLETE, Press Enter | |
At Slackware Linux Setup, select EXIT and press Enter | |
Shut down Slackware 4.0 | |
# umount /mnt | |
# shutdown -h now | |
INIT: Switching to runlevel: 0 | |
INIT: Sending processes the TERM signal | |
Terminated | |
INIT: Sending processes the KILL signal | |
INIT: no more processes left in this runlevel | |
Close the qemu window | |
Then start qemu and verify that Slackware 4.0 boots. | |
iris:~$ ./qemu-slack40.sh | |
The default LILO configuration waits 20 minutes at the boot menu. | |
LILO | |
Welcome to the LILO Boot Loader! | |
Please enter the name of the partition you would like to boot | |
at the prompt below. The choices are: | |
Linux - Linux (ext2fs partition) | |
boot: | |
Press Enter to continue past the LILO boot: menu. | |
Welcome to Linux 2.2.6. | |
darkstar login: root | |
Password: | |
... | |
Fix long LILO timeout | |
darkstar:~# cp /etc/lilo.conf /etc/lilo.bak | |
darkstar:~# sed -e 's/1200/3/' </etc/lilo.bak >/etc/lilo.conf | |
darkstar:~# lilo | |
Added Linux * | |
Create an account, let's call it hermes. | |
darkstar:~# groupadd -g 1000 hermes | |
darkstar:~# useradd -u 1000 -g 1000 -d /home/hermes -m hermes | |
darkstar:~# passwd hermes | |
While we're at it, check out the disk usage. | |
darkstar:~# df | |
Filesystem 1024-blocks Used Available Capacity Mounted on | |
/dev/hda1 495210 310386 159266 66% / | |
Not bad, full install takes 310 MB. :) Now shut down. | |
darkstar:~# shutdown -h now | |
... | |
Power down. | |
Close the qemu window. | |
Let's look at the disk usage on the host system. | |
iris:~$ ls -l Qemu/slack40/slack40.raw | |
-rw-r--r-- 1 ben ben 524288000 ... | |
iris:~$ du -sk Qemu/slack40/slack40.raw | |
328136 Qemu/slack40/slack40.raw | |
This shows that slack40.raw is a 500 MB disk image and it takes | |
328 MB of space on the host system. | |
# Jack In To Sneakernet | |
Look ma, no network stack! It is possible to network BasLinux | |
through qemu, but out of nostalgia i want to use sneakernet. | |
Create scripts to mount and unmount the Slackware 4.0 disk image. | |
This will allow copying files between the host system and the | |
Slackware 4.0 guest. | |
iris:~$ cat >mount-slack40.sh <<'__EOF__' | |
#!/bin/sh | |
disk="/home/ben/Qemu/slack40/slack40.raw" | |
log="/mnt/fuse/slack40.log" | |
dir="/mnt/slack40" | |
part="1" | |
# truncate log | |
cat /dev/null >"$log" | |
# set up loop device for disk image | |
loop=$(losetup -f) | |
losetup -P -f "$disk" | |
loopdev="${loop}p${part}" | |
# mount it | |
sleep 1 | |
mount "$loopdev" "$dir" | |
__EOF__ | |
iris:~$ chmod a+rx mount-slack40.sh | |
iris:~$ cat >unmount-slack40.sh <<'__EOF__' | |
#!/bin/sh | |
disk="/home/ben/Qemu/slack40/slack40.raw" | |
dir="/mnt/slack40" | |
# unmount the filesystem | |
umount "$dir" | |
# find loop device | |
loop=$(losetup -a | grep "$disk\$" | cut -d : -f 1) | |
# detach loop device | |
losetup -d "$loop" | |
__EOF__ | |
iris:~$ chmod a+rx unmount-slack40.sh | |
# Install BasLinux 3.5 | |
While BasLinux can boot a system to an X11 desktop using two | |
floppies, it is not convenient to do so in Qemu. Fortunately, | |
BasLinux also provides a pre-configured Qemu disk image. | |
Download the BasLinux disk image. | |
BasLinux 3.5 Qemu disk image | |
BasLinux 3.5 other files | |
"Install" BasLinux disk image. | |
iris:~$ mkdir -p Qemu/baslinux | |
iris:~$ cd Qemu/baslinux | |
iris:~/Qemu/baslinux$ unzip ~/Downloads/bl3-5qem.zip | |
Archive: /home/ben/Downloads/bl3-5qem.zip | |
inflating: BL3-5qemu.img | |
iris:~/Qemu/baslinux$ cd | |
Make a Qemu startup script. 8 MB RAM should be plenty for X11. | |
With starting X11, 4 MB RAM would be plenty. | |
iris:~$ cat >qemu-baslinux.sh <<'__EOF__' | |
#!/bin/sh | |
DISK="/home/ben/Qemu/baslinux/BL3-5qemu.img" | |
SLACK="/home/ben/Qemu/slack40/slack40.raw" | |
KERNEL="/home/ben/Qemu/baslinux/zimage" | |
MACH="pc-i440fx-9.2,dump-guest-core=off,mem-merge=off,usb=off" | |
SAND="on,obsolete=deny,elevateprivileges=deny,spawn=deny" | |
SAND="${SAND},resourcecontrol=deny" | |
qemu-system-i386 \ | |
-accel kvm \ | |
-machine "$MACH" \ | |
-overcommit mem-lock=off \ | |
-no-user-config \ | |
-sandbox "$SAND" \ | |
-msg timestamp=on \ | |
-cpu max \ | |
-m 8M \ | |
-global i8042.kbd-throttle=on \ | |
-device VGA \ | |
-hda "$DISK" \ | |
-hdb "$SLACK" \ | |
-display sdl,gl=off,grab-mod=rctrl \ | |
-rtc base=localtime | |
__EOF__ | |
iris:~$ chmod a+rx qemu-baslinux.sh | |
iris:~$ ./qemu-baslinux.sh | |
This will boot BasLinux to the following screen. | |
BasLinux boot screenshot | |
Press Enter to go to a shell prompt. | |
Configure easy access to Slackware 4.0 filesystem. | |
/<#>echo "/dev/hdb1 /mnt ext2 noauto 0 0" >>/etc/fstab | |
Configure X11. | |
/<#>Xsetup | |
... | |
Which screen resolution do you want? | |
(A) 640x480 (standard VGA) | |
(B) 640x480x15 (more colors) | |
(C) 800x600x15 (Super VGA) | |
C | |
Which port is your mouse on? | |
(P) PS/2 mouse (little round plug) | |
... | |
P | |
How many buttons does your mouse have? | |
(2) two buttons | |
(3) three buttons | |
3 | |
Change the default font for rxvt. | |
~<#>cp .Xdefaults Xdefaults.bak | |
~<#>sed -e 's/9x15/fixed/' <Xdefaults.bak >.Xdefaults | |
Shut down BasLinux. | |
/<#>poweroff | |
The system is halted. Press Reset or turn off power. | |
Power down. | |
Close the qemu window. | |
# Compile Toolset And Copy Into BasLinux | |
BasLinux doesn't have awk, dialog, nor ed. Let's fix that. | |
First download some source code. | |
iris:~$ BASE=https://invisible-island.net/archives | |
iris:~$ NAME=dialog-1.3-20250116.tgz | |
iris:~$ curl -o $NAME $BASE/dialog/$NAME | |
iris:~$ NAME=mawk-1.3.4-20250131.tgz | |
iris:~$ curl -o $NAME $BASE/mawk/$NAME | |
iris:~$ BASE=gopher://tilde.pink/9/~bencollver/files/dos/editor | |
iris:~$ NAME=ed1d.zip | |
iris:~$ curl -o $NAME $BASE/ed/$NAME | |
dialog 1.3 (20250116) source code | |
mawk 1.3.4 (20250131) source code | |
Beattie ed source code | |
Now copy the sources into the Slackware 4.0 VM. | |
iris:~$ su - | |
Password: | |
iris:~# /home/ben/mount-slack40.sh | |
iris:~# cd /home/ben | |
iris:/home/ben# cp dialog-1.3-20250116.tgz ed1d.zip \ | |
mawk-1.3.4-20250131.tgz /mnt/slack40/home/hermes/ | |
iris:/home/ben# ./unmount-slack40.sh | |
iris:/home/ben# exit | |
Boot Slackware 4.0 to build the tools. | |
iris:~$ ./qemu-slack40.sh | |
Login as root for some local fixes to the headers. | |
Welcome to Linux 2.2.6 | |
darkstar login: root | |
Password: | |
Linux 2.2.6. | |
No mail. | |
darkstar:~# cp /usr/include/wchar.h /usr/include/wchar.bak | |
darkstar:~# sed \ | |
-e 's/^\(typedef unsigned \)int \(wint_t;\)$/\1\2/' \ | |
</usr/include/wchar.bak \ | |
>/usr/include/wchar.h | |
darkstar:~# cp /usr/include/ncurses.h /usr/include/ncurses.bak | |
darkstar:~# sed \ | |
-e 's/^typedef long int wint_t;$/typedef unsigned wint_t;/' \ | |
</usr/include/ncurses.bak \ | |
>/usr/include/ncuirses.h | |
darkstar:~# exit | |
logout | |
Login as hermes. | |
Welcome to Linux 2.2.6 | |
darkstar login: hermes | |
Password: | |
Linux 2.2.6 | |
No mail. | |
Prepare destination directories for toolset. | |
darkstar:~$ mkdir -p baslinux/bin | |
darkstar:~$ mkdir -p baslinux/man | |
Do a static build of the dialog command. | |
darkstar:~$ tar zxf dialog-1.3-20250116.tgz | |
darkstar:~$ cd dialog-1.3-20250116 | |
darkstar:~/dialog-1.3-20250116$ LDFLAGS=-static ./configure | |
... | |
darkstar:~/dialog-1.3-20250116$ make | |
... | |
darkstar:~/dialog-1.3-20250116$ cp dialog ~/baslinux/bin/ | |
darkstar:~/dialog-1.3-20250116$ GROFF_NO_SGR=1 TERM=dumb groff \ | |
-Tascii -man dialog.1 | col -b | tr -d '\r' >dialog.txt | |
darkstar:~/dialog-1.3-20250116$ gzip -c <dialog.txt >dialog.gz | |
darkstar:~/dialog-1.3-20250116$ cp dialog.gz ~/baslinux/man/ | |
darkstar:~/dialog-1.3-20250116$ cd | |
darkstar:~$ strip baslinux/bin/dialog | |
Do a static build of Beattie ed. | |
darkstar:~$ unzip ed1d.zip | |
... | |
darkstar:~$ cd ed1d/src | |
darkstar:~/ed1d/src$ sed -e 's/i586-pc-msdosdjgpp-//' \ | |
-e 's/ed32\.exe/ed/' <Makefile.dj >Makefile | |
darkstar:~/ed1d/src$ cp ed.c ed.bak | |
darkstar:~/ed1d/src$ echo '#define _PROTOTYPE(a, b) a b' >ed.c | |
darkstar:~/ed1d/src$ cat ed.bak >>ed.c | |
darkstar:~/ed1d/src$ make LDFLAGS=-static | |
... | |
darkstar:~/ed1d/src$ cp ed ~/baslinux/bin/ed | |
darkstar:~/ed1d/src$ cd .. | |
darkstar:~/ed1d$ tr -d '\r' <doc/ed.txt | gzip -c >ed.gz | |
darkstar:~/ed1d$ cp ed.gz ~/baslinux/man/ed.gz | |
darkstar:~/ed1d$ cd | |
darkstar:~$ strip baslinux/bin/ed | |
Do a static build of mawk. | |
darkstar:~$ tar zxf mawk-1.3.4-20250131.tgz | |
darkstar:~$ cd mawk-1.3.4-20250131 | |
darkstar:~/mawk-1.3.4-20250131$ LDFLAGS=-static ./configure | |
darkstar:~/mawk-1.3.4-20250131$ make | |
darkstar:~/mawk-1.3.4-20250131$ cp mawk ~/baslinux/bin/ | |
darkstar:~/mawk-1.3.4-20250131$ gzip -c <man/mawk.txt >mawk.gz | |
darkstar:~/mawk-1.3.4-20250131$ cp mawk.gz ~/baslinux/man/ | |
darkstar:~/mawk-1.3.4-20250131$ cd | |
darkstar:~$ strip baslinux/bin/mawk | |
Shut down Slackware 4.0 virtual machine. | |
darkstar:~$ su - | |
Password: | |
darkstar:~# shutdown -h now | |
... | |
Power down. | |
Close the Slackware 4.0 qemu window. | |
Boot the BasLinux virtual machine. | |
iris:~$ ./qemu-baslinux.sh | |
At "Please press Enter to activate this console." press Enter | |
Now copy the freshly compiled toolset into the BasLinux VM. | |
/<#>cd root | |
~<#>mount /mnt | |
~<#>cp /mnt/home/hermes/baslinux/bin/* /usr/bin/ | |
~<#>cp /mnt/home/hermes/baslinux/man/* /usr/man/ | |
~<#>ln -s /usr/bin/mawk /usr/bin/awk | |
~<#>umount /mnt | |
~<#>startx | |
~<#>poweroff | |
# Flip-Card, Unix Style | |
Earlier this week i wrote about porting the Flip-Card demo | |
application from TRS-80 BASIC to FreeBASIC. For comparison, now i | |
will port this demo application to a Unix shell script using awk and | |
the dialog command. I intend for the data files to be compatible | |
with the original BASIC code, so FLIP.DAT can be copied as is. | |
FLIP.BAS for FreeBASIC and QBASIC.EXE | |
I wrote the initial script using busybox awk on Alpine Linux. | |
Then i adapted it to run in mawk on BasLinux. The main problem i | |
ran into was that BasLinux lacks the `mktemp` command. I wrote a | |
small shell script function to replace `mktemp` on BasLinux. | |
For whatever reason, it has color output on the console and | |
monochrome on rxvt. | |
flip.sh main menu screenshot | |
flip.sh edit card screenshot | |
flip.sh main menu screenshot (X11) | |
flip.sh edit card screenshot (X11) | |
Here are links for the script and a sample data file. | |
flip.sh | |
FLIP.DAT | |
tags: occ2025,retrocomputing | |
# Tags | |
occ2025 | |
retrocomputing |