# Prefix 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: => https://www.youtube.com/watch?v=DUD1V1UnoTI The Magick Smoke 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. => to_gem Here's the current source # Here we are again ## Saturday 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. ## BBC repair 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. ## Necromancy > (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. ## Surgery 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. # Necromancy pt 2 ## It lives 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. => bbcresources/PSU%20Repair bbcresources/PSU Repair [0] ## The programs 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). => bbcresources/images bbcresources/images [1] ## The corruption 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`: ``` 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 ## Working ``` Expected output 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 ``` Extracting files 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 ``` BASIC 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? ``` xxd 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 http://bbc.nvg.org/doc/bbcfaq-0.01.txt [2] ``` C 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 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. # Necromancy pt 3 ## What have I done? 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. ## So moving on 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]: => https://xania.org/200711/bbc-basic-v-format here [4] > 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. # Proposal I'm apparently talking about this at CampGND sooo... ## Title The Magic Smoke ## Summary 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. ## Description 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. # Necromancy pt 4 ## Loaded the program to the BBC 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.