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
<gopher://tilde.pink/1/~bencollver/ia/
details/Slackware_Linux_4.0_Walnut_Creek_June_1999>

Slackware 4.0 mirror (FTP)
<ftp://ftp.mirrorservice.org/sites/ftp.slackware.com/pub/slackware/
slackware-4.0>

Slackware 4.0 mirror (gopher)
<gopher://ftp.icm.edu.pl/1/packages/linux-slackware/slackware-4.0/>

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
<gopher://tilde.pink/9/~bencollver/files/dos386/util/baslinux/
bl3-5qem.zip>

BasLinux 3.5 other files
<gopher://tilde.pink/1/~bencollver/files/dos386/util/baslinux/>

"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
<gopher://tilde.pink/I/~bencollver/log/
2025-07-19-occ-baslinux-slackware-4.0-and-flip-card/boot1.png>

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
<https://invisible-island.net/archives/dialog/
dialog-1.3-20250116.tgz>

mawk 1.3.4 (20250131) source code
<https://invisible-island.net/archives/mawk/
mawk-1.3.4-20250131.tgz>

Beattie ed source code
<gopher://tilde.pink/9/~bencollver/files/dos/editor/ed/ed1d.zip>

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
<gopher://tilde.pink/1/~bencollver/log/
2025-07-14-occ-freebasic-qbasic-and-wm-tweaks/>

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
<gopher://tilde.pink/I/~bencollver/log/
2025-07-19-occ-baslinux-slackware-4.0-and-flip-card/con1.png>

flip.sh edit card screenshot
<gopher://tilde.pink/I/~bencollver/log/
2025-07-19-occ-baslinux-slackware-4.0-and-flip-card/con2.png>

flip.sh main menu screenshot (X11)
<gopher://tilde.pink/I/~bencollver/log/
2025-07-19-occ-baslinux-slackware-4.0-and-flip-card/x1.png>

flip.sh edit card screenshot (X11)
<gopher://tilde.pink/I/~bencollver/log/
2025-07-19-occ-baslinux-slackware-4.0-and-flip-card/x2.png>

Here are links for the script and a sample data file.

flip.sh
<gopher://tilde.pink/0/~bencollver/log/
2025-07-19-occ-baslinux-slackware-4.0-and-flip-card/flip.sh>

FLIP.DAT
<gopher://tilde.pink/9/~bencollver/log/
2025-07-19-occ-baslinux-slackware-4.0-and-flip-card/FLIP.DAT>

tags: occ2025,retrocomputing

Tags
====

occ2025
<gopher://tilde.pink/1/~bencollver/log/tag/occ2025/>
retrocomputing
<gopher://tilde.pink/1/~bencollver/log/tag/retrocomputing/>