Jeff Epler's blog

4 September 2022, 2:11 UTC

Recent keyboard deeds


I made several USB HID keyboard conversions recently. They all use CircuitPython. The hardware setup is not documented as none are worthy of being called finished projects at this point, but the source code gives an idea what connections are needed. One or more of these may be the subject of a future Adafruit Learning System Guide.

Click a triangle to see the full code as an embedded github gist. (Note: if you're viewing this in a RSS reader, you may have to click through to get the embeds. Sorry!)

Commodore 16 Keyboard

Used an Adafruit KB2040. Gratuitous use of asyncio. The keymap needs work to be usable, but it's a good start. Direct gist link.

IBM XT "Model F" Keyboard

Used an Adafruit QT PY RP2040. This layout is AWFUL, the "beloved" iteration of the Model F was for AT computers, with a layout a lot more like a modern keyboard (aside from the placement of the Esc and Ctrl keys anyway) Direct gist link.

Tandy 1000 Keyboard

Used an Adafruit Feather RP2040. The trickiest, as caps lock and num lock are handled in the firmware; and there are some real oddities about the layout compared to the keyboards we're used to. This keyboard also needed the most clean-up but mechanically it's 100%. Direct gist link.

[permalink]

31 August 2022, 2:14 UTC

Don't wreck your system with miniconda/anaconda


I guess this software is a tolerable way to install those libraries and packages needed for so many machine learning things written in Python. But annoyingly, it wants to "go to the head of the line" in front of system Python. This is reallllyyyy not what I want.

I noticed that the little blob it deposits in ~/.bashrc can easily be surrounded with a function definition. So, now to activate anaconda in the current shell, but never replace/hide system python in a normal shell, I can just type "fml".

fml () {
# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/home/jepler/miniconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
    eval "$__conda_setup"
else
    if [ -f "/home/jepler/miniconda3/etc/profile.d/conda.sh" ]; then
        . "/home/jepler/miniconda3/etc/profile.d/conda.sh"
    else
        export PATH="/home/jepler/miniconda3/bin:$PATH"
    fi
fi
unset __conda_setup
# <<< conda initialize <<<
}

Now I don't feel quite so worried that having it present on the system is going to interfere with system software or with software I've installed to work with system software via pip.

[permalink]

15 April 2022, 16:23 UTC

Generate the 64 GCR values used by Apple DOS 3.3 and ProDos


for i in range(128):
    b = f"{i:07b}"                    # All these tests apply to the low 7 bits
    if '000' in b: continue           # 3 consecutive zeros disallowed
    if b.count('00') > 1: continue    # only one pair of consecutive 0s allowed
    if not '11' in b: continue        # one pair of consecutive 1s required 
    print(hex(i | 128), bin(i | 128)) # top bit is always a 1

[permalink]

15 April 2022, 2:14 UTC

An interesting finding about Apple DOS 3.3 diskettes


I can't be the first to have noticed this, but if somebody wrote about it years ago there's no way a search engine today will turn it up since they over-value recency and pay little attention to little sites with niche information. So here's my write-up. It feels a little inconclusive, but so be it. I imagine that these disks were mastered in an unsual way, rather than by duplicating a disk written on an Apple II using normal Apple II RWTS code.

I've been working on an open source tool to convert .a2r to .woz. While doing so, I got pretty low level with the Apple flux encoding.

This encoding varied over the years, and of course what really matters is what would work on real machines in the wild.

But one central claim about Apple floppy formats is that early DOS before 3.3 used the repeated bit sequence "1111 1111 0" to allow the floppy interace's state machine to synchronize with the stream of bits on the floppy. Starting with DOS 3.3 and continuing with ProDOS, and ProDOS, the bit sequence "1111 1111 00" is used instead. The newer sequence (also called FF40, because its hex value is FF and it takes 10 bits or 40 microseconds to transmit; the old code is also called FF36) is longer, but fewer repetitions are required to guarantee synchronization.

So I was surprised to see the following when I peered into "DOS 3.3 System Master [1983] - Disk 1, Side A.a2r" from CowgodA2R on archive.org (as are all the a2r files I inspected for this blog post):

111111110    FF36
111111110    FF36
111111110    FF36
111111110    FF36
111111110    FF36
111111110    FF36
111111110    FF36
111111110    FF36
111111110    FF36
111111110    FF36
111111110    FF36
111111110    FF36
111111110    FF36
111111110    FF36
111111110    FF36
111111110    FF36
111111110    FF36
111111110    FF36
111111110    FF36
111111110    FF36
11111111     FF
11010101     D5
10101010     AA
10010110     96
11111111     FF
11111110     FE
10101010     AA
10101010     AA
10101111     AF
10101010     AA
11111010     FA
11111110     FE
11011110     DE
10101010     AA

That's right, the FF36 sequence appears in this DOS 3.3 floppy from 1983. Essentially the same sequence is seen on ProDOS User's Disk - Disk 1, Side A.a2r.

An even odder sequence is seen on the 1980 edition of DOS 3.3:

1111111100   FF40
1111111100   FF40
1111111100   FF40
1111111100   FF40
1111111100   FF40
1111111100   FF40
1111111100   FF40
1111111100   FF40
1111111100   FF40
1111111100   FF40
111111110    FF36
1111111100   FF40
11111111     FF
11111111     FF
11001111     CF
11110011     F3
11111100     FC
11111111     FF
11010101     D5
10101010     AA
10010110     96
11111111     FF
11111110     FE
10101010     AA
10101010     AA
10101011     AB
10101110     AE
11111110     FE
11111010     FA
11011110     DE
10101010     AA

The CF/F3/FC/FF sequence would be an FF40 sequence if the earlier FF bytes hadn't already left you synchronized, but .. there's absolutely no reason for it!

Finally, a disk from the "non-originals" section, which I assume means it's cracked software, has the sequence I expect (more or less) based on reading documentation from the time as well as modern emulator source code:

1111111100   FF40
1111111100   FF40
1111111100   FF40
1111111100   FF40
1111111100   FF40
1111111100   FF40
1111111100   FF40
1111111100   FF40
1111111100   FF40
1111111100   FF40
1111111100   FF40
11111111     FF
11010101     D5
10101010     AA
10010110     96
11111111     FF
11111110     FE
10101010     AA
10101010     AA
10101010     AA
10101011     AB
11111111     FF
11111111     FF
11111111     FF
11111111     FF
11101000     E8
10111111     BF
11111100     FC

[permalink]

15 March 2022, 21:13 UTC

An interesting Disk ][ Interface Card Fault


tl;dr: I recently got into 8-bit Apple retrocomputing due to my work with Adafruit. I had a Disk II setup that couldn't write to any floppy. I fixed it by replacing a 74LS05 IC on the Disk II Interface Card.

read more…

29 January 2022, 19:38 UTC

Stuff I did in 2021...


Here are some of the things that came up in my inventory of last year's deeds:
  • 25 posts on this blog
  • 21 posts on the Adafruit blog
  • 11 guides on the Adafruit learn system
  • 2301 contributions on github
  • 6 3D printed designs shared with the world
  • 3 circuit sculptures
  • 1 PCB design (& got much more comfortable with kicad)
  • Got comfortable using FreeCAD
  • Fave Projects: CircuitPython WWVB Clock & WWVB Observatory
  • 6+ inter-state trips
Here's to creating & sharing a lot more things in 2022.

[permalink]

5 January 2022, 3:44 UTC

Where should CircuitPython go in 2022?


Looking back at 2021

Some of the goals I proposed for 2021 have been accomplished, yay!

  • Support at least one new microcontroller family (I may have known the RP2040 was coming when I said that)
  • Partially addressed the problem of the time required to build CircuitPython core with changes to GitHub CI
  • circup and bundlefly greatly ease the problem of gathering items from the bundles for a particular application
  • In the Adafruit Learn System, we got much more systematic about how programs and their assets are organized
  • The bluetooth workflow is in the wild and people are using it, such as with the PyLeap app for Apple phones.

At a personal level, I accomplished one of the goals I listed, which was to improve my skills at 3D modeling and in particular I have become reasonably competent at part design using FreeCAD.

Some items we made progress on, but there's always room for further improvement:

  • Continue to help people grow into the roles of reviewer and contributor
  • JP's CircuitPython Parsec and Scott and FoamyGuy's livestreams are great, but I'm sure there's room for more "how to" video content around CircuitPython.

Some big pieces of progress we made that I didn't even anticipate (but wish I had) were

  • Getting up to date with MicroPython, and then continuing to merge in their new releases
  • Releasing asyncio support for CircuitPython
  • Adding typing stubs to the core and types to many libraries in the bundle to work better in advanced IDEs

Looking forward to 2022

I'm not a big picture visionary about where the project should head. Lots of times it's modest or even invisible changes that give me the most satisfaction.

I look forward to implementing new drivers for hardware I wouldn't have dreamed of working on (reading from old DOS floppy drives, perfect example), adapting old algorithms into CircuitPython (let's do more image processing or maybe start doing audio processing), and finding small efficiency improvements and firmware size savings when they're needed.

I want to both learn more about and improve asyncio. A personal project goal would be to have an interactive display that continues to update & respond to input even while doing wifi requests. I don't think this works right now (I could be wrong), and I don't know how much is needed in order to make it work.

I look forward to hearing all about the projects you (yes, you) are planning to do in 2022; let's figure out if CircuitPython is the right coding language for those projects, and if it's not let's figure out if there are sensible additions that will make it work.

[permalink]

7 December 2021, 15:07 UTC

The Most Surprising Optimization I've Seen Lately


It seems that under some conditions, gcc (such as gcc 10.1 targeting amd64 linux with -O optimization) compiles the following bad C++ code into non-leaking code. In fact, the generated code is equivalent to return 3; without any call to an allocating function:

class T {
    public:
    T(int i) : i(i) {}
    int i;
};

int should_leak_memory() { return (new T(3))->i;}

[permalink]

3 November 2021, 21:27 UTC

80columns

31 October 2021, 14:17 UTC

Estimating WWVB Signal Health

30 October 2021, 21:12 UTC

Use printf() in Arduino programs

21 October 2021, 0:23 UTC

WWVB Observatory

All older entries
Website Copyright © 2004-2021 Jeff Epler