This is a near verbatim conversion of a bunch of my raw working notes taken
straight from my grimoire about my adventures in necromancing a BBC Micro B
which had its power supply blow up whilst I was writing a program to draw a
pentagram. I did a talk about this at CampGNDd 2020 which is linked below:
This page is partly to share those notes and partly to test out code I wrote
for converting markdown to gemtext. As you'll see, inline links have been
turned into references to links in the block below.
The tabernacle is a fucking mess, I've already managed to accidentally kick
over my bass and break the cigarbox computer's case. It might be fixable, we'll
see, but I need better storage in here.
The parts arrived and hilariously all the information I apparently need is on a
CD. I could spin it up if I were to also spin up an old Sony VAIO I have with a
PCMCIA CD drive. I have two CDs with software on now and both are from
retrocomputer supply places, the SPI drivers (I'm guessing it's Windows drivers
for writing BEEB.MMB files) and the instructions and information for recapping.
The irony of exactly the **wrong** kind of technological anachronism is not
lost on me.
(It is now the subsequent Friday)
I made a grasp for getting some of the data off of that disk by ripping apart
Hannah's old Dell laptop and scavenging the DVD drive. I basically just need to
get a USB->Laptop DVD SATA cable in order to use this scavenged limb for
reading and archiving the data. Of course, I knew this last Saturday but I
still haven't bought it because of the cumulative effects of a fucking shopping
list on my likelihood of actually purchasing what I need - I try to optimize,
get annoyed and give up.
I need to not do that.
When I opened my main Linux laptop this morning it had those stupid fucking
graphical glitches from before POST. After a couple of reboots and an upgrading
the kernel in some vague hope it was like an NVRAM thing or something, I opened
it **right** up and reseated the LCD cable and it's fine now
Quick fix. This is why you pay for good kit and the right tools to open
electronics.
I successfully resurrected the BBC using the capacitor kit I ordered, and I'm
glad I waited to be able to access the disk or I never would have bothered and
it has a shitload of information as archived here under [bbcresources/PSU Repair][1].
The main pdf was an excellent set of instructions, but there's a bunch
more of use in there.
I've written the programs which I'd posted photos of on Instagram (currently in
[bbcresources/images][2]) to the SD card and I can now run
them at will! The SD card extender bought the farm probably immediately as I
bent the cable (it was useless to me without the bend anyway) which is a pain -
perhaps I can build my own or find a longer one, or maybe even make an
extension cable for the User port (which could be pretty cool).
The SD card isn't listing properly. I think this is due to my using DUTILS to
attempt to reformat the filesystem. I've taken an image (outside of this
repository) of the filesystem and have confirmed that I can find the data on
there using `xxd`:
00efe3f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00efe400: 0d00 0a08 20eb 2034 0d00 1410 20e8 2078 .... . 4.... . x 00efe410: 632c 2079 632c 2072 0d00 1e1b 20f2 6472 c, yc, r.... .dr 00efe420: 6177 6369 7263 6c65 2878 632c 2079 632c awcircle(xc, yc, 00efe430: 2072 290d 0028 1e20 f264 7261 7770 656e r)..(. .drawpen 00efe440: 7461 6772 616d 2878 632c 2079 632c 2072 tagram(xc, yc, r 00efe450: 290d 0032 0620 e00d 003c 1d20 dd20 f264 )..2. ...<. . .d 00efe460: 7261 7763 6972 636c 6528 7863 2c20 7963 rawcircle(xc, yc 00efe470: 2c20 7229 0d00 4613 2020 20ec 2078 6320 , r)..F. . xc 00efe480: 2b20 722c 2079 630d 0050 1e20 2020 e320 + r, yc..P. . 00efe490: 7468 6574 6120 3d20 3130 20b8 2033 3630 theta = 10 . 360 00efe4a0: 2088 2031 300d 005a 1a20 2020 2020 7820 . 10..Z. x 00efe4b0: 3d20 722a 9b28 b228 7468 6574 6129 290d = r*.(.(theta)). 00efe4c0: 0064 1a20 2020 2020 7920 3d20 722a b528 .d. y = r*.( 00efe4d0: b228 7468 6574 6129 290d 006e 1920 2020 .(theta))..n. 00efe4e0: 2020 df20 7863 202b 2078 2c20 7963 202b . xc + x, yc + 00efe4f0: 2079 0d00 780e 2020 20ed 2074 6865 7461 y..x. . theta 00efe500: 0d00 8206 20e1 0d00 8c20 20dd 20f2 6472 .... .... . .dr 00efe510: 6177 7065 6e74 6167 7261 6d28 7863 2c20 awpentagram(xc, 00efe520: 7963 2c20 7229 0d00 9613 2020 20ec 2078 yc, r).... . x 00efe530: 632c 2079 6320 2b20 720d 00a0 1d20 2020 c, yc + r.... 00efe540: 7468 6574 6120 3d20 3336 3020 2d20 3930 theta = 360 - 90 00efe550: 202b 2031 3434 0d00 aa12 2020 20e3 2069 + 144.... . i 00efe560: 203d 2031 20b8 2036 0d00 b41a 2020 2020 = 1 . 6.... 00efe570: 2078 203d 2072 2a9b 28b2 2874 6865 7461 x = r*.(.(theta 00efe580: 2929 0d00 be1a 2020 2020 2079 203d 2072 )).... y = r 00efe590: 2ab5 28b2 2874 6865 7461 2929 0d00 c819 *.(.(theta)).... 00efe5a0: 2020 2020 20df 2078 6320 2b20 782c 2079 . xc + x, y 00efe5b0: 6320 2b20 790d 00d2 1c20 2020 2020 7468 c + y.... th 00efe5c0: 6574 6120 3d20 7468 6574 6120 2b20 3134 eta = theta + 14 00efe5d0: 340d 00dc 0a20 2020 ed20 690d 00e6 0620 4.... . i.... 00efe5e0: e10d ff00 0000 0000 0000 0000 0000 0000 ................ 00efe5f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00efe600: 0d00 0a08 20eb 2037 0d00 1419 20f2 7072 .... . 7.... .pr 00efe610: 696e 7467 7269 6d6d 7761 7265 2831 2c31 intgrimmware(1,1 00efe620: 290d 001e 0920 f13a 20f1 0d00 2806 20e0 ).... .: ...(. . 00efe630: 0d00 641c 20dd 20f2 7072 696e 7467 7269 ..d. . .printgri 00efe640: 6d6d 7761 7265 2878 2c20 7929 0d00 6e77 mmware(x, y)..nw 00efe650: 2020 20f1 208a 782c 2079 293b 203a 20ef . .x, y); : . 00efe660: 2031 3436 2c20 3535 2c20 3433 2c20 3130 146, 55, 43, 10 00efe670: 362c 2031 3135 2c20 3533 2c20 3533 2c20 6, 115, 53, 53, 00efe680: 3535 2c20 3535 2c20 3533 2c20 3535 2c20 55, 55, 53, 55, 00efe690: 3535 2c20 3533 2c20 3533 2c20 3332 2c20 55, 53, 53, 32, 00efe6a0: 3533 2c20 3131 392c 2031 3233 2c20 3332 53, 119, 123, 32 00efe6b0: 2c20 3535 2c20 3130 352c 2031 3036 2c20 , 55, 105, 106, 00efe6c0: 3131 350d 0078 7320 2020 f120 8a78 2c20 115..xs . .x, 00efe6d0: 7920 2b20 3129 3b20 3a20 ef20 3134 3620 y + 1); : . 146 00efe6e0: 3533 2c20 3935 2c20 3130 362c 2039 362c 53, 95, 106, 96, 00efe6f0: 2035 322c 2035 332c 2035 332c 2035 332c 52, 53, 53, 53, 00efe700: 2035 332c 2035 332c 2035 332c 2035 332c 53, 53, 53, 53, 00efe710: 2035 332c 2033 322c 2035 332c 2035 332c 53, 32, 53, 53, 00efe720: 2031 3036 2c20 3332 2c20 3535 2c20 3130 106, 32, 55, 10 00efe730: 352c 2031 3036 0d00 827d 2020 20f1 208a 5, 106...} . . 00efe740: 782c 2079 202b 2032 293b 203a 20ef 2031 x, y + 2); : . 1 00efe750: 3436 2c20 3131 372c 2031 3232 2c20 3130 46, 117, 122, 10 00efe760: 362c 2033 322c 2035 332c 2035 332c 2035 6, 32, 53, 53, 5 00efe770: 332c 2035 332c 2035 332c 2035 332c 2035 3, 53, 53, 53, 5 00efe780: 332c 2035 332c 2031 3137 2c20 3131 372c 3, 53, 117, 117, 00efe790: 2035 332c 2035 332c 2031 3036 2c20 3437 53, 53, 106, 47 00efe7a0: 2c20 3533 2c20 3130 362c 2031 3036 2c20 , 53, 106, 106, 00efe7b0: 3131 320d 00c8 0620 e10d ff2b 0070 7269 112.... ...+.pri 00efe7c0: 6e74 6772 696d 6d77 6172 6500 4619 0000 ntgrimmware.F... 00efe7d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
Notably here things like the line numbers (which are different from the
original) are not immediately evident, nor can you see the word "MODE" anywhere
(although you can clearly see a 4 and a 7 respectively at the beginning of each
program), nor does `DEF PROC` so it looks like the programs are not stored in a
strictly plaintext format. It should be pretty trivial to extract the original
program however.
I'm going to attempt to re-image the SD card with the one supplied on the disk
and see if that a) loads b) comes back corrupt. If it's successful I'll
re-record my programs to the uncorrupted disk image. At least I won't have to
write down all those fucking numbers again.
- [*] Test out empty BEEB.MMB
- Can `*DCAT` and `*DIN 0 0`
- 512 disk images and `*CAT` is full of shit
- [*] Try to build a BEEB.MMB with Elite in it
- This worked but was still not presenting the same file
- Turns out after some snooping around in `*HELP` that I was initializing
with the wrong command
- There's a `*DMMC` command which shows all of the things I'm **expecting**
to see rather than `*CARD`
- Correcting this in 00002
oholiab@blame/pts/5:~/mnt > sudo beeb dinfo 0 Catalogue for Disk 0: GRIMM Disk title: GRIMM (2) Disk size: &320 - 200K Boot Option: 0 (None) File count: 1 Filename: Lck Lo.add Ex.add Length Sct $.SATAN FF1900 FF8023 000020 002
The above is a file I wrote whilst using the BBC
oholiab@blame/pts/5:~/mnt > sudo beeb dgetfile 0 ../GRIMM Extracting from disk 0: GRIMM Saving $.SATAN as SATAN oholiab@blame/pts/5:~/mnt > cd ../GRIMM oholiab@blame/pts/5:~/GRIMM > ls SATAN SATAN.inf oholiab@blame/pts/5:~/GRIMM > cat SATAN "HAIL SATAN" oholiab@blame/pts/5:~/GRIMM > cat SATAN.inf $.SATAN FF1900 FF8023 CRC=91C4% oholiab@blame/pts/5:~/GRIMM > xxd SATAN 00000000: 0d00 0a13 20f1 2022 4841 494c 2053 4154 .... . "HAIL SAT 00000010: 414e 220d 0014 0b20 e520 8d54 4a40 0dff AN".... . .TJ@.. oholiab@blame/pts/5:~/GRIMM > 00000000: 0d00 0a13 20f1 2022 4841 494c 2053 4154 .... . "HAIL SAT 00000010: 414e 220d 0014 0b20 e520 8d54 4a40 0dff AN".... . .TJ@..
This file is
10 PRINT "HAIL SATAN" 20 GOTO 10
Notably the file begins with `0d00` and ends with `0dff` which seems like some
good demarking. Can we extract similar from our disk image above?
00efe400: 0d00 0a08 20eb 2034 0d00 1410 20e8 2078 .... . 4.... . x 00efe410: 632c 2079 632c 2072 0d00 1e1b 20f2 6472 c, yc, r.... .dr 00efe420: 6177 6369 7263 6c65 2878 632c 2079 632c awcircle(xc, yc, 00efe430: 2072 290d 0028 1e20 f264 7261 7770 656e r)..(. .drawpen 00efe440: 7461 6772 616d 2878 632c 2079 632c 2072 tagram(xc, yc, r 00efe450: 290d 0032 0620 e00d 003c 1d20 dd20 f264 )..2. ...<. . .d 00efe460: 7261 7763 6972 636c 6528 7863 2c20 7963 rawcircle(xc, yc 00efe470: 2c20 7229 0d00 4613 2020 20ec 2078 6320 , r)..F. . xc 00efe480: 2b20 722c 2079 630d 0050 1e20 2020 e320 + r, yc..P. . 00efe490: 7468 6574 6120 3d20 3130 20b8 2033 3630 theta = 10 . 360 00efe4a0: 2088 2031 300d 005a 1a20 2020 2020 7820 . 10..Z. x 00efe4b0: 3d20 722a 9b28 b228 7468 6574 6129 290d = r*.(.(theta)). 00efe4c0: 0064 1a20 2020 2020 7920 3d20 722a b528 .d. y = r*.( 00efe4d0: b228 7468 6574 6129 290d 006e 1920 2020 .(theta))..n. 00efe4e0: 2020 df20 7863 202b 2078 2c20 7963 202b . xc + x, yc + 00efe4f0: 2079 0d00 780e 2020 20ed 2074 6865 7461 y..x. . theta 00efe500: 0d00 8206 20e1 0d00 8c20 20dd 20f2 6472 .... .... . .dr 00efe510: 6177 7065 6e74 6167 7261 6d28 7863 2c20 awpentagram(xc, 00efe520: 7963 2c20 7229 0d00 9613 2020 20ec 2078 yc, r).... . x 00efe530: 632c 2079 6320 2b20 720d 00a0 1d20 2020 c, yc + r.... 00efe540: 7468 6574 6120 3d20 3336 3020 2d20 3930 theta = 360 - 90 00efe550: 202b 2031 3434 0d00 aa12 2020 20e3 2069 + 144.... . i 00efe560: 203d 2031 20b8 2036 0d00 b41a 2020 2020 = 1 . 6.... 00efe570: 2078 203d 2072 2a9b 28b2 2874 6865 7461 x = r*.(.(theta 00efe580: 2929 0d00 be1a 2020 2020 2079 203d 2072 )).... y = r 00efe590: 2ab5 28b2 2874 6865 7461 2929 0d00 c819 *.(.(theta)).... 00efe5a0: 2020 2020 20df 2078 6320 2b20 782c 2079 . xc + x, y 00efe5b0: 6320 2b20 790d 00d2 1c20 2020 2020 7468 c + y.... th 00efe5c0: 6574 6120 3d20 7468 6574 6120 2b20 3134 eta = theta + 14 00efe5d0: 340d 00dc 0a20 2020 ed20 690d 00e6 0620 4.... . i.... 00efe5e0: e10d ff00 0000 0000 0000 0000 0000 0000 ................
It sure does (albeit not on the 2 byte boundary like I was expecting but
whatever)
So in theory if we can recreate the .inf file, we should be able to inject the
original program back in?
According to `MMB_Utils`, this is of the format:
`Filename LOAD EXEC [Locked] CRC=####`
Looking some more at the documentation, an example for `beeb putfile` shows the
contents of an arbitrary .inf as:
`$.FOO FF1900 FF8023 Locked CRC=AB7A`
Which means that the load/exec are the same as my previous arbitrary example -
likelihood is I can just re-use these.
The CRC is apparently different, however
[http://bbc.nvg.org/doc/bbcfaq-0.01.txt][3]
shows this to be some sort of checksum for the file, and gives an example of
both BBC BASIC and the C function which calculates it for some bbc disk
utility:
http://bbc.nvg.org/doc/bbcfaq-0.01.txt [2]
unsigned int crc=0; while (1) { fread(&byte,1,1,fp); if (feof(fp)) break; length +=1; crc ^=(byte << 8); for(int k=0;k<8;k++) { if (crc & 32768) crc=(((crc ^ 0x0810) & 32767) << 1)+1; else crc =crc << 1; } }
Using this I've produced
[bbcresources/spi/crc_calc/crccalc][4] which
I've used to reproduce the CRC in SATAN.inf from SATAN
bbcresources/spi/crc_calc/crccalc.c [3]
Now I should be able to use `xxd -r` to reproduce the binary data for my
program and reconstruct the inf file.
I used `cat PENT.hexdump | cut -f2- -d " " | xxd -r -p > PENT` in order to
reset the offset to 0 and then reconstructed the .inf by copying the extant one
for a BBC constructed program, replacing the CRC and then truncating the line
terminator with `truncate -s -1 PENT.inf`
I then did the following:
oholiab@blame/pts/5:~ > beeb blank_ssd GRIMM.ssd Blank GRIMM.ssd created oholiab@blame/pts/5:~ > beeb putfile GRIMM.ssd GRIMM/* oholiab@blame/pts/5:~ > beeb title GRIMM.ssd GRIMM GRIMM.ssd updated oholiab@blame/pts/5:~ > cd mnt oholiab@blame/pts/5:~/mnt > sudo beeb dkill 0 Deleting disk 0: GRIMM Are you sure (Y/N)? y Removed oholiab@blame/pts/5:~/mnt > sudo beeb dput_ssd 0 ../GRIMM.ssd Disk ../GRIMM.ssd (GRIMM) written to 0 oholiab@blame/pts/5:~/mnt > sudo beeb dcat 0: GRIMM 1: ELITE oholiab@blame/pts/5:~/mnt > sudo beeb dinfo 0 Catalogue for Disk 0: GRIMM Disk title: GRIMM (1) Disk size: &320 - 200K Boot Option: 0 (None) File count: 2 Filename: Lck Lo.add Ex.add Length Sct $.SATAN FF1900 FF8023 000020 004 $.PENT FF1900 FF8023 0001F2 002
The BBC says it is a "BAD PROGRAM" (but it will run one called SATAN lolz)
From the output of `*DUMP` compared between both files I think I'll need to at
least remove the trailing 00 bytes after the final `DO FF`
> beeb list PENT 10 MODE 4 20 INPUT xc, yc, r 30 PROCdrawcircle(xc, yc, r) 40 PROCdrawpentagram(xc, yc, r) 50 END 60 DEF PROCdrawcircle(xc, ycRIGHT$(RIGHT$(" Bad program (expected ^M)
The equivalent part of the hexdump:
00000050: 290d 0032 0620 e00d 003c 1d20 dd20 f264 )..2. ...<. . .d 00000060: 7261 7763 6972 636c 6528 7863 2c20 7963 rawcircle(xc, yc 00000070: c2c2 0722 90d0 0461 3202 020e c207 8632 ..."...a2......2
So it looks like the `c2c2` maps to `RIGHT$(RIGHT$(`
00000010: 632c 2079 632c 2072 0d00 1e1b 20f2 6472 c, yc, r.... .dr 00000020: 6177 6369 7263 6c65 2878 632c 2079 632c awcircle(xc, yc, 00000030: 2072 290d 0028 1e20 f264 7261 7770 656e r)..(. .drawpen
It is somehow shifted by half a byte because of an erroneous `c` wtaf.
If I:
- use `xxd -p` on the file
- edit a nibble from the output
- realign the newline boundary (use a macro, you're stoned)
- Append nul nibble before `0dff` at the end
- `xxd -r -p` out to the program
- `beeb list PENT` to see where the next bug is
I can see
> beeb list PENT 10 MODE 4 20 INPUT xc, yc, r 30 PROCdrawcircle(xc, yc, r) 40 PROCdrawpentagram(xc, yc, r) 50 END 60 DEF PROCdrawcircle(xc, yc, r) 70 MOVE xc""RIGHT$(ADVAL0 Bad program (expected ^M)
This time it was missing a `0` in a `20` (space)
oholiab@blame/pts/11:~/GRIMM > beeb list PENT 10 MODE 4 20 INPUT xc, yc, r 30 PROCdrawcircle(xc, yc, r) 40 PROCdrawpentagram(xc, yc, r) 50 END 60 DEF PROCdrawcircle(xc, yc, r) 70 MOVE xc + r, yc 80 FOR theta = 10 TO 360 STEP 10 90 x = r*COS(RAD(theta) Bad program (expected ^M)
I think this one might be the line number for the next line - the next trailing
0x29 `)` is defintely there as is the line trailing (and probably ending)
0x0D00, (look what I'm learning!), and the next two bytes appear to be a
variable byte and a line starting 0x1A.
So the line number being the variable byte
The next line should be 100, the hex is 0x64 which is 100.
At this point we stop because I'm too wasted to go any further.
Okay so it looks like on the back of last time I've build some semblance of a
hex editor in emacs. It's called nibble-mode.
We're still looking at fixing this file. Nothing's particularly obvious, so I
thinkt he problem is in the line metadata.
From [here][5]:
Each line is stored as a sequence of bytes:
0x0d [line num hi] [line num lo] [line len] [data…]
The line number is as you’d expect — the line number — with one exception.
The maximum line number is 65279 (0xfeff) as the special marker 0x0d 0xff is
used to signify the end of the program. The line length includes the three
preceding bytes, making the maximum length of a line 251 bytes.
Looks like that's for the **full** line including the leading `0d`
oholiab@blame/pts/6:~/GRIMM > beeb list ../PENT.bin 10 MODE 4 20 INPUT xc, yc, r 30 PROCdrawcircle(xc, yc, r) 40 PROCdrawpentagram(xc, yc, r) 50 END 60 DEF PROCdrawcircle(xc, yc, r) 70 MOVE xc + r, yc 80 FOR theta = 10 TO 360 STEP 10 90 x = r*COS(RAD(theta) Bad program (expected ^M) oholiab@blame/pts/6:~/GRIMM > beeb list ../PENT.bin 10 MODE 4 20 INPUT xc, yc, r 30 PROCdrawcircle(xc, yc, r) 40 PROCdrawpentagram(xc, yc, r) 50 END 60 DEF PROCdrawcircle(xc, yc, r) 70 MOVE xc + r, yc 80 FOR theta = 10 TO 360 STEP 10 90 x = r*COS(RAD(theta)) 100 y = r*SIN(RAD(theta)) 110 DRAW xc + x, yc + y 120 NEXT theta 130 ENDPROC 140 DEF PROCdrawpentagram(xc, yc, r) 150 MOVE xc, yc + r 160 theta = 360 - 90 + 144 170 FOR i = 1 TO Bad program (expected ^M)
This looks like newline formatting again because there's definitely a trailing
space and the number 6 (which is correct).
Next line is `0d00b41a`
Line 180 (correct), length 26 (correct).
So it's not that.
00000150: 3020 2b20 3134 340d 00aa 1220 2020 e320 0 + 144.... . 00000160: 6914 203d 2031 20b8 2036 0d00 b41a 2020 i. = 1 . 6.... 00000170: 2020 2078 203d 2072 2a9b 28b2 2874 6865 x = r*.(.(the
This looks pretty suspect - the `14` after the `i` at the beginning is not
present in other examples of for loops (maps to the last failing line)
> beeb list ../PENT.bin2 10 MODE 4 20 INPUT xc, yc, r 30 PROCdrawcircle(xc, yc, r) 40 PROCdrawpentagram(xc, yc, r) 50 END 60 DEF PROCdrawcircle(xc, yc, r) 70 MOVE xc + r, yc 80 FOR theta = 10 TO 360 STEP 10 90 x = r*COS(RAD(theta)) 100 y = r*SIN(RAD(theta)) 110 DRAW xc + x, yc + y 120 NEXT theta 130 ENDPROC 140 DEF PROCdrawpentagram(xc, yc, r) 150 MOVE xc, yc + r 160 theta = 360 - 90 + 144 170 FOR i = 1 TO 6 180 x = r*COS(RAD(theta)) 190 y = r*SIN(RAD(theta)) 200 DRAW xc + x, yc + y 210 theta = theta + 144 220 NEXT i 230 ENDPROC Bad program (expected ^M)
The last byte is `0xdf` which needs to be 2 bytes, 0x0d and 0xff.
This fixes it!
Generated a new CRC for the .inf file and truncated it. Will test tomorrow.
I'm apparently talking about this at CampGND sooo...
The Magic Smoke
In the age of COVID-19 we're all remaining totally normal and absolutely not trying to study the ancient (and modern) arts of the occult via retrocomputing for reasons.
We all know not to let the magic smoke out, but how often do we honestly
pretend it's magic for the sake of theatrics and because there's nothing else
going on?
A few weeks back whilst trying to write a program to draw a pentagram on a
greenscreen CRT to an SD card via a BBC Micro B in order to summon demons or
something probably, the sheer occult power was too much and it blew up one of
the capacitors.
This talk covers how you can spin out a series of lazy mistakes into a winding
narrative of religious research, esotericism, chaos magick and being an
internet wizard. And BBC Micro power supply repair and SD card filesystem
recovery. And writing hex editors in elisp.
It loads now but it does not work! If you `CHAIN` the program it declares
"MISTAKE AT LINE 90" after taking your input.
If you `LIST` the program, it correctly lists up to just after the `x` on line
90 and then clears the screen and continues to list at the position after,
either the space before the equals or the equals (entirely possible it's a
spurious control character).
Hopefully we can make short work of this as it's unlikely it's corrupt line
metadata.
000000a0: 2088 2031 300d 005a 1b20 2020 2020 7820 . 10..Z. x 000000b0: 103d 2072 2a9b 28b2 2874 6865 7461 2929 .= r*.(.(theta)) 000000c0: 0d00 641a 2020 2020 2079 203d 2072 2ab5 ..d. y = r*.
There it is, a spurious byte before the equals.
We remove it and obviously the program now fails to parse because there's too
many bytes!
We drop the preceeding `0d005a1b` (which we previously bumped because we
thought **that** was wrong) back down to `0d005a1a`
The program continues to list correctly.
We load it in to the BBC and it works just fine! We've successfully binary
repaired a corrupt disk image of a BBC BASIC program! Like FUCKING WIZARDS.