TPUG Library CD – disk image contents, mostly

TPUG – Toronto PET Users Group still publishes its software library for Commodore computers. You can buy it for $20.00 (Cdn) plus shipping and handling. Yes, it still makes TPUG money to sell it this way. No, it’s not available online.

The scanned library catalogues are available as PDF: About the TPUG Library. They’re searchable via web search engines:
Google: site:tpug.ca amiga “puzzle maker”. The search is only as good as the OCR in the scan, but is better than nothing.

What you can’t do is search inside the disk images themselves. The files I made below might help with that, especially once search engines get hold of them:

Each line has the disk name and then the name of the file in that disk image, something like:

TPUG C64/A-Monthly Disks/(c)aaa.d64 : 0 "tpug may86(c)aaa" ac 2a
TPUG C64/A-Monthly Disks/(c)aaa.d64 : 23 "autoload" prg
TPUG C64/A-Monthly Disks/(c)aaa.d64 : 119 "infusr/2.0.txt" seq
TPUG C64/A-Monthly Disks/(c)aaa.d64 : 13 "infbot/2.1" prg
 …

Note that I haven’t uploaded any of the disk images. Please don’t ask me for them.

Possibly Painless Network Printing from your Raspberry Pi

Printing from computers goes through waves of being difficult to being easy, then back to difficult again. This is likely due to the cycles of technology, complexity and user demand flow in and out of sync. I think we’re at peak annoyance right now.

It’s even harder with Raspberry Pis, as when printer drivers support Linux, 90% of them are for x86 or x86_64 computers only. ARM doesn’t get a look in. But one technology does actually seem to help: network printers that support IPP — Internet Printing Protocol.

We had an old Brother laser printer that just got slower and crankier and less useful as a printer, so yesterday I got a new Brother DCP-L2550DW to replace it. It says it supports Linux in the spec, but I knew not to be too optimistic with my Raspberry Pis. And indeed, it was seen on the network but no driver was found. I had a sad.

What turned my frown upside down was finding out about Raspbian’s cups-ipp-utils package. For desktop use, install it this way:

sudo apt install cups-ipp-utils system-config-printer

(leave off system-config-printer if you’re running from the terminal.)

On the desktop, open up Preferences → Print Settings and add a new printer. Yes, it prompts for your user password which you may have forgotten. I’ll wait while you try to remember it …

Now under Network Printers, you should see a device you recognize. Pick the one that says IPP network printer somewhere:

IPP network printer

Here’s where the magic happens: you actually want to pick the generic driver for once:

Select Generic (recommended) manufacturer

And again, the IPP utilities package will have picked the right driver for you:

Just go with what the driver suggests

Changing the name and location is optional:

Your new printer’s almost ready to go!

Hit Apply, and you should be printing!

(Hey, printer manufacturers have been known to be evil and make good, working stuff suddenly not work. IPP is supposed to make everything sparkly again, but I can’t guarantee that something wicked won’t come this way.)

Just what 2019 needs: the QBasic Online Help Index

QBasic (from olddos.exe) running nicely under dosbox on Linux

Only umpteen years late, I bring you the

QBasic Online Help Indexhttps://scruss.com/qbasic_hlp/

It’s the QuickHelp file from Microsoft’s ancient-but-still-useful QBasic interpreter for MS-DOS. I converted it to HTML, and made some minor cleanups so it would work better on the web.

So if you’ve got a hankering to understand the parameters for MKSMBF$ or know the syntax of PRINT USING, I’ve got your back.

HSV(ish) Colour Wheel in Python

Years back I wrote something about HSV colour cycling for Arduino. Things have moved on: we’re all writing code in MicroPython/CircuitPython now and 8-bit micro-controllers are looking decidedly quaint. Yes, yes; some of you must still write code in PIC assembly language and I’m sure that’s very lovely for you indeed don’t @ me.

If you look at the output of a typical HSV to RGB algorithm, the components map something like this:

Hue between 0-1, with saturation and value set to 1. Output range 0-1 for each component

These lines remind me so much of sine waves, if very blocky ones. The red trace in particular is just the cosine function, with the input range of 0..2π and the output range of -1..1 both mapped to 0..1. The green and blue traces are just the red trace shifted horizontally by ⅓ and ⅔ respectively.

Since we have transcendental functions in MicroPython, we don’t have to fossick about with linear approximations. The common RGB LED function wheel() uses similar linear interpolation as the graph above. Why make do with blocky cogwheels when you can have a smooth colour wheel?

def cos_wheel(pos):
# Input a value 0 to 255 to get a colour value.
# scruss (Stewart Russell) - 2019-03 - CC-BY-SA
from math import cos, pi
if pos < 0:
return (0, 0, 0)
pos %= 256
pos /= 255.0
return (int(255 * (1 + cos( pos * 2 * pi)) / 2),
int(255 * (1 + cos((pos - 1 / 3.0) * 2 * pi)) / 2),
int(255 * (1 + cos((pos - 2 / 3.0) * 2 * pi)) / 2))
Though you never quite get a pure red, green or blue, the results are pleasing

Quite elegant, I thought. Yeah, it may be computationally expensive, but check next year when we’ll all be running even faster µcs. Certainly none of the mystery switch statements or nested conditionals you’ll see in other code. Just maths, doing its thing.

First half is cosine wheel, second half (after red flash) is linear

Symmetric chamfered extrusion in OpenSCAD

enjoy the quality of the smooth, smooth taper

I like using OpenSCAD, but it has some limitations. While you can linear_extrude() 2D paths into 3D shapes, you can’t get a proper tapered/chamfered extrusion of anything but simple shapes that are symmetric about the origin:

// this is symmetrical …
linear_extrude(height=20, scale=2)square(10, center=true);

// but shift the same square off the origin and this happens …
linear_extrude(height=20, scale=2)translate([20, 20])square(10, center=true);

There are lots of partial attempts at fixing this, many of which end up with ugly results. Some of them even mess up the top surface, which is precisely what I wanted to avoid. My code uses the computationally-intensive minkowski() sum function to replace every vertex of a 2D shape with a many-sided pyramid.

Minkowski sums effectively replace every vertex with another shape, here making a rounded cube from a cube and a sphere:

minkowski() {
cube(10);
sphere(4);
}

One feature of OpenSCAD’s implementation of the Minkowski sum is that the operator takes into account the second shape’s position relative to the origin. So if I take the same cube and apply the minkowski() operator with the same sphere moved away from the origin, I get:

// the same cube, but shifted by the power of minkowski()!
minkowski() {
cube(10);
translate([-15,-15,-15])sphere(4);
}

So I can approximate a tapered extrusion by turning a 2d path into a very thin 3d plate (OpenSCAD’s 2D and 3D subsystems can never meet in the same output) and using a pyramid as the second argument to the operator:

// the component parts, before minkowski()

// thin extrusion of 2D path
linear_extrude(height=0.001)text(“S”, size=24, font=”EB Garamond:style=12 Italic”);

// a 30 degree pyramid with its apex at the origin
rotate_extrude()polygon([ [0,0] , [4, -8], [0, -8] ]);

You get:

minkowski() {
// thin extrusion of 2D path
linear_extrude(height=0.001)text(“S”, size=24, font=”EB Garamond:style=12 Italic”);
// a 30 degree pyramid with its apex at the origin
rotate_extrude()polygon([ [0,0] , [4, -8], [0, -8] ]);
}

In reality, you’d probably use a smaller taper angle, but the example is short rather than pretty. If you’re really picky about correctness, the process leaves the thin extrusion as parallel walls at the bottom of the shape, shown grossly exaggerated here for effect:

hugely exaggerated vertical profile

If you’re working in consumer-grade 3D printing and are using the standard 1 unit = 1 mm scale, the residual parallel section would only be 1 µm thick and way below any realistic layer height. Feel free to remove it, but be warned that this process creates so many facets that the difference() required to remove it will be very time-consuming for no visible difference.

Here’s the code: chamfer_extrude.scad – make sure to rename the txt extension to scad. Or, if you’d prefer, here’s a link to a gist: scruss/chamfer_extrude.scad

Put it in your OpenSCAD library folder, then you can use it like this:

include <chamfer_extrude.scad>; 

chamfer_extrude(height=4, angle=15, $fn=16)text("S", size=24, font="EB Garamond:style=12 Italic", $fn=64);
way smooth s

The library just adds some expected utility and tidiness to the above process. The source includes documentation and examples.

SBC6120 build: day 1(-ish)

SBC6120 (RBC Edition) with all the sockets

Just started on a SBC6120 RBC Edition kit. It’s a DEC PDP-8-compatible single board computer that uses a CMOS chipset from the early 1980s. Yes, it will be very slow, even with the optional speedy 8 MHz oscillator installed. With a 12-bit processor and 32 kilo-words of RAM, this is definitely going to be a Slow Computing device.

Lots and lots of sockets. So many sockets. It’s quite soothing soldering them all in, one hole at a time. It looks like it’ll go more quickly than the Zeta did.

> Does anyone know what each of the pins on the 6502 CPU chip in the Apple II Plus does?
They all plug into the socket on the motherboard to keep the chip from drifting away. – c.s.a2 FAQ of yore

eben’s bbc basic programmes

I wrote this as a comment to Learn to write games for the BBC Micro with Eben – Raspberry Pi, but it didn’t seem to save:

BeebEm? Lawks, that’s a bit old (2006). All the cool (*cough*) kids are running b-em – https://github.com/stardot/b-em – these days. It’s lovingly maintain by Stardot forum members. It’s a little crashy on some Linux platforms, but seems stable on the Raspberry Pi and Raspbian. You may need to install the liballegro5-dev and zlib1g-dev packages to get it to compile.

If you want a native version of BBC BASIC, Richard Russell’s version is pretty neat: http://www.bbcbasic.co.uk/bbcsdl/ . You’ll most likely need to change line 280 to use some variant of the WAIT command to make it playable.

Another native interpreter is Brandy. There’s an ancient one in the repos, but I’m completely taken with the Matrix Brandy fork: https://github.com/stardot/MatrixBrandy . It may need a few packages installed to get it to build (libsdl1.2-dev might be a good first try), but it’s really fast. For cross-platform happiness, change line 280 to WAIT 10. If you stick to using a FOR loop, you might have to have it as high as 2,000,000 on a fast computer!

Lastly, if you want to run the game in a browser, JSBeeb to the rescue: https://bbc.godbolt.org/?autorun&loadBasic=https://gist.githubusercontent.com/scruss/f5a8eb83f28b85d6399142cac460c806/raw/74c4e39de7661bb2e3dd7f435840dd8db7172589/helicopter.bbc
It’s a bit slow in Chromium on a Raspberry Pi, but it does work!

Small things that make me happy …

Chebucto Community Net in Nova Scotia still has all its downloads and instructions for helping to get an Apple II (8 bit) & Apple IIGS (16 bit) online.

Comprehensive Uncle TechTip Simulator

Around 1988–1991 there was a weekly computer magazine in the UK called New Computer Express. This period coincided roughly with the time I was a freelance writer in the same field.

For childish reasons now lost to time, a group of us freelancers had a major hate-on for  NCE’s advice columnist. Writing under the name Uncle TechTip, this columnist seemed to answer most questions with something like “Hmm, I don’t know anything about _____. Maybe a reader can help?” Almost without fail, he’d have readers write in answers for next week’s issue.

Not realizing that Uncle TT’s economy of response was a sly precursor to crowdsourcing websites, the neophyte journo brigade were incensed by his lack of knowledge. One of us wrote an Uncle TechTip Simulator in BASIC, which I recreate from memory for your enjoyment:

10 CLS
15 PRINT " *** Uncle TechTip Simulator ***"
20 PRINT
25 INPUT "What is your question for Uncle TechTip";a$
30 PRINT
35 PRINT "Uncle TechTip's Answer: "
40 PRINT
45 PRINT "Hmm, I don't know anything about"
50 PRINT " ";a$;" ..."
55 PRINT "Maybe a reader can help?"

Using SI prefixes/multipliers in spreadsheets

Note: I’ve lightly tested this with Microsoft Excel (Windows 10), Excel Online, Google Sheets and LibreOffice Calc. It seems to work. Like all spreadsheet data conversions, please verify before trusting your PhD thesis tables to it …

Asked on the GTALUG mailing list the other week:

Does anybody know how to display and work with SI numbers like 10k or 
20M or 40G within LibreOffice?

I came up with the following formula, in this example for data in cell D3:

=IF(LEN(T(D3))=0, D3, CONVERT(VALUE(LEFT(D3, LEN(D3) - 1)),
    RIGHT(D3, 1) & "m", "m"))

which results in:

Input Value
1u 1.00E-06
10u 10.00E-06
100u 100.00E-06
1m 1.00E-03
10m 10.00E-03
100m 100.00E-03
1 1.00E+00
10 10.00E+00
100 100.00E+00
1k 1.00E+03
10k 10.00E+03
100k 100.00E+03
1M 1.00E+06

The right column is displayed in LibreOffice Calc’s newly(ish)-supported engineering notation.

This function works through creative (mis-)use of the CONVERT() function:

  1. if the argument is a numeric value, pass it through;
  2. if the argument is a string, return CONVERT(«numeric part», "«prefix»m", "m"). This is lightly misusing overloading the unit conversion function by going via metres, but it saves having a lookup table.

This function doesn’t work with IEC 60027-2 binary prefixes, but they’re silly and I wouldn’t be caught dead using ’em.

vase mode

I’m still a sucker for vase mode/spiral contour prints … this one made in OpenSCAD:

Thanks to Andrew at ProtoLab for the loan of the PrintrBot. I’ve got a demo at UofT on Wednesday, and my Reach 3D isn’t exactly portable. Yeah, I should probably get a cheap Monoprice printer to lug around to occasional demos, but I’d need to find a donor …

Thingiverse Customizer: a tiny guide

Thingiverse‘s Customizer allows users to customize suitable OpenSCAD models without knowing any OpenSCAD code. While it does have some documentation to help developers along, there’s still a lot of guesswork.

I released my first (working!) Customizer design the other week: Parametric Finger Pen Holder (Vertical). While the docs are the primary source of developer information, you might want to know the following:

  • Customizer assumes that every variable defined before the first module definition in the script is a user parameter. To give it a hint that it should stop displaying variables, add an empty module (such as module naff() { }) after the last variable definition you want Customizer to display.
    (There’s supposed to be a CUSTOMIZER VARIABLES/CUSTOMIZER VARIABLES END comment pair that will do this too, but it didn’t work for me)
  • Customizer will fail if there’s any character other than strict ASCII in the script, and won’t give useful diagnostics about the problem. Check your comments for accents and fancy punctuation
  • Customizer displays a real-time preview of your model. This means the rendering will be a little rough, especially if you use set operations such as union(), difference() and intersection(). If you have to hit F6 to render your model in OpenSCAD properly, it’s going to look a bit off in Customizer
  • If you must use resource-intensive functions such as hull() and minkowski(), try to limit them to 2D paths that are subsequently extruded. Everyone else in the Customizer job queue will thank you
  • Similarly, keep the circle smoothness variables ($fa, $fn, $fs) in sensible ranges
  • Customizer creates a new Thing under your name rather than just letting you download your customized model. You likely want to delete that once you’re finished with it.
    (This also means that Customizer only works for registered Thingiverse users. I can’t see any way around this, unfortunately)

“space acid poisoning …”

Thanks to users sbadger and lurkio on the stardot forum, I’ve been reunited the original BBC BASIC one-liner that begat 2d Star Dodge/Stardodger: Asterisk Tracker!

Asterisk Tracker

It was published in the December 1984 edition of BEEBUG Magazine (vol. 3, issue 7; page 9) and is credited to N. Silver.

It’s impossibly short:

1L=0:REP.L=L+3:MO.4:DR.1279,0:DR.1279,452:MOVE1279,572:DR.1279,1023:DR.0,1023:F.I=1TOL:V.31,RND(32)+5,RND(31),42,30:N.:P.(L-3)/3:X=0:Y=512:REP.PL.69,X,Y:X=X+4:Y=Y-(INKEY-74+.5)*8:U.PO.X,Y)=1ORX=1280:U.X<1280:V.7:REP.U.INKEY-99:RUN

It makes extensive use of BBC BASIC’s abbreviations, and the writeup even warns

… Here the programs are extensively abbreviated so that the line will fit into Basic’s keyboard buffer. Because of this, you cannot edit a LISTed version, and so, to allow for errors, it is best to spool out a copy of the text to tape/disc initially. This can be achieved as follows:

*SPOOL PROGRAM
type in program
*SPOOL

The program unwinds to something much more understandable:


   10 L=0
   20 REPEAT
   25   L=L+3
   30   MODE 4
   40   DRAW 1279,0
   50   DRAW 1279,452
   60   MOVE 1279,572
   70   DRAW 1279,1023
   80   DRAW 0,1023
   90   FOR I=1 TO L
  100     VDU 31,RND(32)+5,RND(31),42,30
  110   NEXT
  120   PRINT (L-3)/3
  130   X=0
  140   Y=512
  150   REPEAT
  155     PLOT 69,X,Y
  160     X=X+4
  170     Y=Y-(INKEY(-74)+.5)*8
  180   UNTIL POINT(X,Y)=1 OR X=1280
  190 UNTIL X<1280
  200 VDU 7
  210 REPEAT UNTIL INKEY(-99)
  220 RUN

The instructions are typical of the day:

The first game (called ‘Asterisk Tracker’) is a very simple game in which you have to guide a ‘snake’ across the screen, whilst avoiding the stars. As the game progresses, more and more stars will be displayed, and the ease of the game rapidly disappears. The Return key guides the ‘snake’ upwards, but it moves down if Return is not pressed. Aim your ‘snake’ for the gap in the wall, and don’t touch any objects as this causes instant death from space acid poisoning!

Um, yeah, N. Silver, whatevs …

It’s pretty amazing that three type-ins could fit on a page: especially when you consider that the BEEBUG magazine was A5!

beebug vol 3 issue 7 page 9

If you want to play it (and who wouldn’t? We wasted days on this game) you can either run this Asterisk Tracker alone in the browser: Asterisk Tracker, or lurkio has combined them into one, and put them here: Beebug One-Line Games (Asterisk Tracker, a Truffle Hunt clone, and a treasure hunt).

I just wish Graeme Smith were still with us to play this.

moar 10PRINT nonsense

10 Print CHR$(205.5+RND(1)): Goto 10

but this still owns it:

10 PRINT CHR$(199+2*RND);: GOTO 10

I found I can get this to preload in an emulator, but you still have to type RUN and hit return. See, look: http://scruss.com/cpc/6128s.html?stardoj.dsk/10%20PRINT%20CHR$(199+2*RND);:%20GOTO%2010

Rob Manuel’s British Council Tile / Bus Fabric Sim

Rob’s British Council Tile / Bus Fabric Sim — described here: Amstrad BASIC that approximates the tiling schemes that a local council might have used for a municipal building in the 1970s — is a joy. So few colours!

No, really: this *was* the seat pattern on Western SMT buses circa 1979

Because I care (and don’t if you don’t), here’s the Locomotive BASIC source, lovingly typed into the Caprice32 emulator then extracted as text using iDsk:


10 ' British Council Tile / Bus Fabric Sim
20 ' by Rob Manuel 2018
30 '
40 ' z/x - change char up/down (ascii)
50 ' space - random palette
60 ' c - show ascii val, inks & pause
70 ' v - random character (128+ ascii)
80 ' b - random char and cols
90 ' n - fill with same line & pause
100 'i - input ascii value
110 '
120 ON BREAK GOSUB 260:MODE 1:LOCATE 1,26
130 DEF FNs=INT(RND*255)
140 SYMBOL 255,FNs,FNs,FNs,FNs,FNs,FNs,FNs,FNs
150 DEF FNp=INT(RND*4)
160 DEF FNi=INT(RND*26)
170 GOSUB 470
180 GOSUB 270
190 o$="":i$=INKEY$
200 IF i$<>"" THEN GOSUB 380
210 FOR i=1 TO 40
220 w$=CHR$(14)+CHR$(FNp)+CHR$(15)+CHR$(FNp)
230 w$=w$+CHR$(c):o$=o$+w$:NEXT i
240 store$=o$
250 PRINT o$;:GOTO 190
260 CALL &BC02:PAPER 0:PEN 1:END
270 aa=FNi:bb=FNi:cc=FNi:dd=FNi
280 INK 0,aa:INK 1,bb:INK 2,cc:INK 3,dd
290 BORDER aa
300 GOSUB 320:RETURN
310 IF c>255 THEN c=32:IF c<32 THEN c=255
320 LOCATE 1,1:PAPER 0:PEN 1
330 PRINT "C:"c;
340 PRINT CHR$(c);
350 PRINT " ";
360 PRINT "I:"aa;bb;cc;dd;
370 LOCATE 1,26:RETURN
380 IF i$=" " THEN GOSUB 270:RETURN
390 IF i$="z" THEN c=c-1:GOSUB 310:RETURN
400 IF i$="x" THEN c=c+1:GOSUB 310:RETURN
410 IF i$="c" THEN GOSUB 310:CALL &BB18:RETURN
420 IF i$="i" THEN LOCATE 1,1:INPUT "ASCII?",c:GOSUB 310:RETURN
430 IF i$="v" THEN GOSUB 470:GOSUB 310:RETURN
440 IF i$="b" THEN GOSUB 270:GOSUB 470:GOSUB 310:RETURN
450 IF i$="n" THEN FOR i=1 TO 25:PRINT store$;:NEXT:CALL &BB18:RETURN
460 RETURN
470 c=INT(RND*128)+127:RETURN

And if you really care, here’s an emulator snapshot — BritishCouncilTileSim.zip

Update: I modified the code slightly (essentially, all INT(RND*n) to RND MOD n) so it would compile with Hisoft Turbo Basic. It works! It’s faster!

Snapshot: BritishCouncilTileSimCompiled.zip

Apple IIgs: before and after graphics

Unless you have the heavy analogue Apple CRT that was specially made for it, composite video output on the Apple IIgs is utterly dismal:

Apple IIgs: composite to LCD display

Adding an Apple IIgs → SCART cable through a SCART to HDMI converter is much better:

Apple IIgs: via SCART and HDMI

There’s still a little bit of shimmer to the background, but at least text is legible.