The distraction of distraction-free word processors

I’m currently not writing at least three books. At least one of them, I am convinced, is an amazingly good idea. I’ve written a dozen chapters, at least one of which doesn’t make me cringe when I read it back, but when it comes to the actual paperwork of finishing one… it just doesn’t happen.

The Freewrite

Of course a bad workman blames his tools, so when the Freewrite distraction-free word processor came out a few years ago, I was smitten. It’s a self-contained, portable word processor with an e-Ink display (I love e-Ink displays, they seem indistinguishable from magic to me) that allows you to type and backs up your work to the cloud via wifi but does not allow you to browse the web, Twitter etc, hence ‘distraction-free’. But it’s expensive. Way too expensive for what it is at around $600 – though it is currently on sale for less. As this review points out, you could buy a cheap laptop and a copy of Scrivener and still have money left over to buy a whole other laptop if you break the first one. I think the slowness of the eInk display updating as you type would also be a killer for me. My typing is poor, I really do like to correct typos as I go.

I’ve discovered that there’s no better distraction from writing than researching distraction-free word processors. Here are some personal boxes any solution needs needs to tick:

The wish list

  • Constant on-screen word count – essential
  • Inexpensive
  • Portable
  • Nice clacky keyboard
  • Rich text format editing – italics and bold are a must, ability to change text size and font not so much.
  • Default text size should be large or able to make it large for my poor eyesight.
  • Save in .rtf for similar format so docs can be opened easily by many other apps
  • Paste unformatted text by default
  • Pale yellow page background, not white – or customisable
  • Left, right, centre align options
  • Icons on toolbar not necessary, can just use keyboard shortcuts and menu
  • Show clearly if file is currently unsaved
  • Open by default with last document open
  • Smart quotes
  • Possible cloud backup but it could just save in a Dropbox folder
  • Possible FTP backup
  • Possible timestamp save for keeping each version – option perhaps? Every save gets a new date and timestamp.
  • Images probably not required for fiction
  • Tables probably not required for fiction
  • Runs full-screen

There are lots of apps out there, this is not an exhaustive list by any means, but here are some alternatives to the Freewrite that I’ve considered:

Pen and paper

When the Freewrite was first announced and I was swooning over it on Twitter, someone sent me a photo of a notepad and a biro with the caption ‘my ultimate distraction-free word processor’. And they have a point. Only the other day I read that Sylvia Townsend Warner ‘began her self-proclaimed “accidental career” as a poet after she was given paper with a “particularly tempting surface” and who wrote her first novel, Lolly Willowes; or, The Loving Huntsman (1926), because she “happened to find very agreeable thin lined paper in a job lot.”’ [https://www.britannica.com/biography/Sylvia-Townsend-Warner]

Would that it were so simple.

I need to be able to edit, process text. I need it to be backed up. It’ll need typing up eventually, so although pen and paper is great for jotting down ideas, I am going to eschew the methods of all those great writers, including Muriel Spark, who always wrote in the same kind of notebook from an Edinburgh stationers, all those writers who just need a good pen, good stationery and start writing at the beginning and keep going until they finish.

So I really do need a gadget.

Coding my own: WoolfWrite

How hard could it be to write a word processor? Not actually that hard, I discovered.

The Freewrite was originally called Hemingwrite, so years ago I fantasised a cheap gadget called WoolfWrite in response. More recently I decided to explore coding one in Python using the simple GUI tool guizero, and here’s how far I have got with it: https://github.com/blogmywiki/woolf-write.

WoolfWrite screenshot

There’s plenty this does not do, it’s plain text-only for example so no bold or italics, but it ticks a few important boxes: on-screen constant word count, large text, no distracting bells and whistles, it warns you when your work is unsaved. The code is pretty simple and if you know even a little bit of Python you can modify this to suit your needs and it’ll run on pretty much any Mac, Windows or Linux machine with Python 3 and guizero installed. If you run it in a Dropbox folder, for example, that could even look after the cloud backups for you.

WordGrinder

Now this found a place in my heart when I discovered that this text editor that runs in a terminal window was written by someone as a distraction from writing a novel. Its author, David Given, is a man after my own heart.

WordGrinder on a PiZero

WordGrinder ticks a lot of boxes: it’s fuss-free, and although it’s intended to be run in a window on your desktop, I managed to get an old Raspberry Pi Zero to boot straight to it with no GUI installed at all (pictured below stuck to the underside of a nice old clacky Apple USB keyboard). The major drawback so far is bot being able to get italics to display on either my Mac or on the Pi – indeed on the Pi italics and bold show up the same, which is not great, but I was able to fiddle with a few settings on the computer to get it to display the text in a lovely retro green reminiscent of the Amstrad PCW word processor. And this boots fast using DietPi as its OS.

piZero stuck to keyboard

I love the timestamped auto-save feature, I considered something very similar for WoolfWrite but there are some drawbacks – no cloud backup yet, though maybe a cron job and FTP could work, or perhaps just adding a USB stick for backup. It also uses an esoteric file format rather than RTF or similar, but it can export in various different useful file formats.

If I can fix the italics issue on a GUI-less PiZero and sort out some backup, then this is an insanely cheap solution. The PiZero was a freebie with a magazine and was unused, and the keyboard was also junk. With a small HDMI display I’d have something close to this intriguing home-made version of the Freewrite: https://www.instructables.com/FeatherQuill-34-Hours-of-Distraction-Free-Writing/ .

I’d love to tweak WordGrinder myself, but that’s beyond my coding skills just now as it’s written in C. Which brings me to…

Code or modify my own using Python / PyQT

I did actually get quite far with following this tutorial and modifying the code to suit my needs, which I could do because it’s written in Python. It’s tantalisingly close to what I want, but PyQT is a bit of a heavy dependency and I found this project’s native HTML file format a bit infuriating – although a kind soul on Twitter helped me work out how to export the text to RTF format. (I did want to add RTF format to WoolfWrite, but heavens RTF is a weird format when you look inside it!)

I may come back to this and do a proper write-up of how I stripped this down and made it do more of the things I wanted (like adding a constant on-screen word count, basic formatting keyboard shortcuts and filename display) and fewer of the things I didn’t (e.g. removed infuriatingly duplicated tool-tips and made it paste unformatted text by default – you have no idea how happy the latter made me! All apps and OSs should paste unformatted text by default, you almost always want it to match the destination not the source.)

gileswrite screenshot

.

Google Drive or Dropbox Paper
Google Drive is what I currently use for creative writing and there’s a lot to be said for it, though obviously both of these require internet access and a laptop and all the distractions that affords. Dropbox Paper is nice because its formatting is so limited – for example you can’t change font, and I strongly approve of that, but its chirpy messages when you open a new document annoy me so much that I’ve started making my own sarcastic ones for WoolfWrite. Also Dropbox Paper has limited file export options and frequently tells me I’ve lost my connection when I know my wifi and broadband are just fine, so I’m ruling it out for the great novel project.
Who do you think you are? Ernest Bleeding Hemingway?

Just use the laptop you already have, turn off the damn internet and write

I admit it’s hard to argue against this, and numerous free and paid-for distraction writing apps are out there for you to use, though I couldn’t find one that did precisely what I wanted, which is why I started trying to write or modify my own. A cheap old netbook and some version of either the Python PyQT app or WordGrinder could well be the way to go.

Remember, a bad workman blames his tools.

A writer writes, always.

The night was hot, wait no, the night, the night was humid. The night was humid, no wait, hot, hot. The night was hot. The night was hot and wet, wet and hot. The night was wet and hot, hot and wet, wet and hot; that’s humid. The night was humid.

“Chapter 1. It was a dark and stormy night…”

Posted in computers, literature, lowendmac, Raspberry Pi | Tagged , , | Leave a comment

Make a simple calculator with guizero & Python

GUI calculator screenshotMaking your own apps, even simple ones, with a GUI still seems to be surprisingly tricky, and this makes it hard to teach, especially if you want to build an app that will run standalone, or near-standalone, on a real computer.

Python is a very popular language for teaching and developing, but its default library for making GUIs, tkinter, is pretty scary and horrible. I have built a few apps for touch screens using it: a radio, an audio play-out system for radio or theatre and a similar cartwall.

Tkinter does give you a lot of control over layout, but I do think it’s way too hard for a beginner, especially a student who’s just getting some confidence with Python and wants to make a ‘real’ app with buttons and widgets.

What is guizero?

This is where guizero comes in. Created by Laura Sach and Martin O’Hanlon at Raspberry Pi, it’s a wrapper round tkinter that makes creating GUIs much more accessible. I was lucky enough to be on a Picademy course where Laura was one of the tutors, and her enthusiasm and ability to make complex things accessible is inspiring and infectious.

If you want to get started with guizero, there’s a great primer on the Raspberry Pi site, and Laura & Martin have also written a book which you can download as a free PDF.

My only previous guizero project was a simple word processor, WoolfWrite. I got slightly obsessed about how word processors lacked an on-screen word counts, so important to anyone writing an essay, job application or being paid by the word! Also, different web forms and apps calculate word counts in different ways, so I decided to write my own to see if I could figure out why. I should probably do a blog post just on that one day, coding is great way to learn, like the time I had to code a solution to the Monty Hall maths problem before I could understand it.

Let’s make a calculator

old desk calculatorLaura and Martin’s book is full of fun games and even a meme generator, but I wanted to make something a bit more prosaic: a calculator app. I wasn’t kidding myself this would be easy: as I discovered when I turned 3 micro:bits into a calculator, calculator UX and UI is surprisingly hard.

My aim was to use the simplest possible Python code, so anyone relatively new to the language could follow it. I also decided not to look at any other calculator and that it should behave pretty much like my ancient solar-powered desk calculator that I retrieved from a dustbin where one of my BBC bosses had thrown it because he disagreed with an answer it had given. To be fair, he had a degree in maths from Cambridge, so he was probably right.

Breaking down the code

I think real, practical projects are a great way to learn, so let’s break it down, chunk by chunk. There are probably more efficient ways of writing the code, this is just what I came up with today. Tomorrow I might write it very differently!

Here is every bit of code in order with some explanations. Note I always use single quotes at they are easier for children to type. You can find the full program here: https://github.com/blogmywiki/guizero-calc

Set-up

# imports -------------------------------
from guizero import App, Text, PushButton

# initialise variables ------------------
displayString = ''
a = False
b = False
result = 0
operator = ''
operatorFlag = False

Here I import the features of guizero that I’m using and initialise the variables. It stores the current displayed number in a string called displayString. a and b are the two numbers you’ll be adding, subtracting etc. result is the answer, operator is the operation you’ll be performing and operatorFlag is used to keep track of whether or not you’ve pressed an operator key.

# app -----------------------------------
app = App(title='MyCalc', layout='grid')
app.bg = '#000000'

This defines the title of the app that appears in the very top of the window. Guizero has a simple mode that just stacks elements on top of each other, but we need to select the grid layout for our calculator as we want buttons in a grid. I’ve also made the background of the app black (#000000) to look a bit like an Apple calculator app.

The functions

# functions -----------------------------
def inputNumber(key):
    global displayString, operatorFlag
    if operatorFlag:
        displayString=''
        operatorFlag = False
    displayString = displayString + key
    display.value = displayString

The first of several functions is inputNumber(). When you click on a number button, the button passes a string like ’7′ to this function which adds the number to the display string and shows it in the display element. If you’ve just pressed an operator key like ‘+’ or ‘x’ it clears the display string ready for the next number.

def operatorKey(key):
    global a, operator, operatorFlag, displayString
    operator = key
    operatorFlag = True
    if not a:
        a = float(displayString)

If you press an operator key, like ‘+’ or ‘-’, the button passes it to this function which assigns it to the operator variable. It sets the flag to say that it’s been pressed and if the first number, a, doesn’t exist because it hasn’t been set, it assigns the current contents of the display as a floating point number to a

def evaluate():
    global a, b, result, operator, displayString
    if not a and not b:
        return
    elif a and not b:
        b = float(displayString)
    if operator == '+':
        result = a + b
    elif operator == '-':
        result = a - b
    elif operator == '/':
        result = a / b
    elif operator == 'x':
        result = a * b
    # stop decimal places appearing for whole numbers
    if result - int(result) == 0:
        result = int(result)
    displayString = str(result)
    display.value = displayString
    a = result

This is the biggy! Evaluate does the calculation.

First, it checks that you have entered two numbers, a and and b.

If you’ve not set either number, it just bails out of the function with the ‘return’ instruction. This could be summarised as ‘come back when you’ve entered some numbers!’

If you’ve set a but not b, it then assigns the current display contents to b.

Then it gets on and performs the relevant calculation of your two numbers, checking that if the floating point result is actually a whole number. If it is, it turns it to an integer variable type to avoid trailing decimal points and zeros being displayed.

It then does one last thing: it assigns the result to the a variable, ready to be calculated on again. This means that, just like on a real calculator, if you press 7 + 2 = you’ll see 9, then if you keep pressing =, 11, 13, 15 etc.

def allClear():
    global a, b, operator, result, displayString
    a = 0
    b = 0
    operator = ''
    result = 0
    displayString = ''
    display.value = '0'

This function allClear() is called if you press the AC (all clear) button. It resets everything back to 0.

def backspace():
    global displayString
    if len(displayString) > 1:
        displayString = displayString[:-1]
        display.value = displayString
    else:
        displayString = ''
        display.value = '0'

Rather than having a CE (clear entry) button I decided to implement a backspace instead. It trims the last character of the display string, unless it’s shorter than 2 characters long, in which case it just clears it.

Layout and buttons

# layout & buttons ----------------------
display = Text(app, text='0', color='#FFFFFF', grid=[1,0,15,1])
display.text_size = 37

display is the area in which the numbers are displayed. I set the initial text to ’0′ and the text colour to white. You can specify fonts, but I decided to leave it to a default font and it looks ok on a Mac at least. The grid statement puts it in the second column with a stupidly large span of 15 columns and 1 row to prevent it moving the buttons too much when the numbers get long. This needs a bit of work as if you divide 22 by 7 the buttons do still spread out a bit.

btn7 = PushButton(app, command=inputNumber, args=['7'], text='7', grid=[0,1])
btn8 = PushButton(app, command=inputNumber, args=['8'], text='8', grid=[1,1])
btn9 = PushButton(app, command=inputNumber, args=['9'], text='9', grid=[2,1])
btn4 = PushButton(app, command=inputNumber, args=['4'], text='4', grid=[0,2])
btn5 = PushButton(app, command=inputNumber, args=['5'], text='5', grid=[1,2])
btn6 = PushButton(app, command=inputNumber, args=['6'], text='6', grid=[2,2])
btn1 = PushButton(app, command=inputNumber, args=['1'], text='1', grid=[0,3])
btn2 = PushButton(app, command=inputNumber, args=['2'], text='2', grid=[1,3])
btn3 = PushButton(app, command=inputNumber, args=['3'], text='3', grid=[2,3])
btn0 = PushButton(app, command=inputNumber, args=['0'], text='0', grid=[1,4])
btnDec = PushButton(app, command=inputNumber, args=['.'], text=' .', grid=[2,4])

btnDiv = PushButton(app, command=operatorKey, args=['/'], text='÷', grid=[3,1])
btnMult = PushButton(app, command=operatorKey, args=['x'], text='x', grid=[3,2])
btnSub = PushButton(app, command=operatorKey, args=['-'], text='-', grid=[3,3])
btnAdd = PushButton(app, command=operatorKey, args=['+'], text='+', grid=[3,4])

btnEquals = PushButton(app, command=evaluate, text='=', grid=[4,4])
btnAC = PushButton(app, command=allClear, text='AC', grid=[4,1])
btnCE = PushButton(app, command=backspace, text='←', grid=[4,2])

All the buttons in a grid! I didn’t try to change their colours because, well, on a Mac you can’t. Buttons should be grey anyway, right?

The grid numbers specify the column and row of each button, staring at 0 as the first column.

You can specify a function to call when you push a button using command=...

If the function takes parameters, like inputNumber or operatorKey, you have to use args=[] to pass it. If you used, say operatorKey(7) instead, the function would fire as soon as you open the app and put a number 7 on the display before you’d even clicked on anything. (Thanks to Matt, Carlos & Laura for helping me figure that out!)

The sneaky infinite loop

# display app loop ------------------------------
app.display()

Finally, this line creates the app loop. It’s important to think of this as an infinite loop that keeps polling the keys for events. As they say in the guizero docs:

You may be used to writing programs which contain loops or make use of the sleep() command, but find when you try to use these with guizero they cause your GUI to freeze. This is because guizero (in common with almost all GUIs) operates an event driven model of programming which may be different to the one you are familiar with.

What did I learn?

- How to create an app with a simple grid of working buttons
- How to pass parameters to functions from inside a button
- Why some of my previous attempts at Python GUIs failed: they run in their own infinite loop and some basic, familiar programming methods don’t work in this strange, parallel, event-driven universe.

Posted in computers | Tagged , | 1 Comment

6502 breadboard computer: part 2

Having started to build a Ben Eater-style, 6502-based breadboard computer a few weeks ago, I’ve started to diverge my design a bit. Ben uses an Arduino Mega to monitor the status of the address and data bus, but I like old computers with blinkenlights and I also like the simplicity of a self-contained computer that doesn’t need an Arduino and another full-sized computer to display the data.

So I decided to keep the 16 LEDs I wired across the address bus, and added 8 new LEDs to the data bus, so I can monitor what’s going on, albeit in binary rather than in hexadecimal on an Arduino console screen.

Flashing an EEPROM

eeprom programmer

If we’re going to write a real program, instead of hard-wiring no operation instructions, we’ll need some sort of memory. The first kind we add is a read-only memory (ROM) so that the program remains when the power is off. This is used in old computers like the KIM-1 and Acorn System 1 to store the monitor program that allows you to enter code on a keypad and show things on an LED display. More complex systems like the Apple ][ and Commodore PET stored a BASIC interpreter in ROM as well as the machine's operating system.

As I want to keep changing the program as I develop the system, I need a kind of ROM that I can modify, which is where the EEPROM (electrically erasable programmable read-only memory) comes in.

It was quite exciting flashing my first ever EEPROM. Back in the day (by which I mean the 1970s) I think EPROMs had to be erased using ultraviolet light and the process took a very long time, but now you can erase and flash a 32K EEPROM in a few seconds. I got an inexpensive programmer from China, which comes with Windows software but, being on a Mac, I installed a command line utility called minipro, which I installed using brew at the MacOS terminal command line:

brew install minipro

I modified Ben Eater's first program to add a loop and some different values. It just loads hex value aa (binary 10101010) into the accumulator, writes that out to memory location 6000, does the same with hex 55 (binary 01010101), and then loops back to the start of the program.

I also modified Ben's short Python program (code below) to create a binary file of exactly the correct length (32k) to fit on the EEPROM, which fills all the empty spaces with NOP (no operation) instructions - ea in hex.

You'll see that memory addresses are given 'backwards', i.e. address 6000 is coded as 00 then 60. This is the way that the 6502 (and some other processors) encode 2-byte addresses. It seems odd, but apparently there's a potential speed gain to be had from doing it this way. It's called little-endian encoding, after the pointless wars in Jonathan Swift's Gulliver's Travels over which end of a boiled egg you should crack open first. And, having done some machine code programming of my own, I finally understand it! The smaller (littler) byte of the two bytes comes first.

The other thing to note here is the 8000 address stored right near the end of the ROM, at locations 7ffc and 7ffd. This is the reset vector, which is super-important. When the 6502 processor is reset, it looks at these memory locations for the address at which it will find its instructions, the program you want it to run. In this build, we connect the EEPROM so that its first byte is at memory location 8000.

rom = bytearray([0xea] * 32768)
rom[0] = 0xa9   #LDA aa
rom[1] = 0xaa
rom[2] = 0x8d   #STA 6000
rom[3] = 0×00
rom[4] = 0×60
rom[5] = 0xa9   #LDA 55
rom[6] = 0×55
rom[7] = 0x8d   #STA 6000
rom[8] = 0×00
rom[9] = 0×60
rom[10] = 0x4c  #JMP 8000
rom[11] = 0×00
rom[12] = 0×80
rom[0x7ffc] = 0×00
rom[0x7ffd] = 0×80

with open(“rom.bin”, “wb”) as out_file:
  out_file.write(rom)

I connected the EEPROM programmer's USB cable to my laptop and burned the binary file created with the Python script on to it using this command:

minipro -p AT28C256 -w rom.bin

Wiring the ROM chip

I used an Atmel AT28C256 32k EEPROM chip. This, I have to say, was an absolute pig to wire up - look how illogical the address bus pins are! Pin 7 is next to pin 12 which is next to pin 14.

atmel eeprom pinout

I'm grateful to Pete Lomas for explaining to me that this illogical layout is caused by trying to maintain compatibility with older EPROMs and ROMs: no-one ever thought they'd be bigger than 1K, and room had to be found for the extra address lines.

So, I connected the EEPROM's address pins 0-14 to address bus pins 0-14 on the 6502 CPU, pin 14 to GND and pin 28 to +5v.

CPU address bus pin 15 goes via an inverter made from a NAND gate to the EEPROM’s CE (chip enable) pin 20. See Ben Eater's video for details. This is to ensure that the EEPROM is only enabled when the CPU is trying to address memory above location 8000.

Pin 27 WE (write enable) is tied high to +5v to prevent it being overwritten.

Pin 22 OE (output enable) is tied low (GND) as we want some output from the ROM.

The EEPROM I/O pins 0-7 are connected to data bus pin 0-7 on the CPU.

Running the program

first instruction annotated

So, I powered it all up. As you'll see from the video at the top of the page, I wasn't sure if it was doing the right thing at first, but when I reset the CPU and single-stepped through the program, I discovered it was working perfectly. The picture above shows its status at address 8000, the first instruction of the program in my EEPROM. The data bus is showing binary 10101001, which is hex 89. 89 is the opcode for the 6502 LDA instruction, which is the first instruction!

I stepped through the whole program and confirmed every LED on the data bus is showing either the instruction opcode, or data being read or written.first program byte by byte

The next steps will be to add the 6522 versatile interface adaptor (VIA) and a display. Ben Eater makes some LEDs blink next, but I feel I have enough blinkenlights, I may skip that and go straight to adding an LCD display driven from the VIA chip.

Eventually I'm going to want to add a keypad. I found a few articles about adding PS/2 keyboards, but I want something simpler and more KIM-1 like. I have some flexible 4x4 matrix keypads, which will do for entering hexadecimal numbers, but I'll need at least 4 more buttons I think to create a self-contained single-board computer: stop, go, up and down. If anyone has any advice about how to attach a small (say 4x5 or 5x5) keypad to a 6502, I'd love to hear it!

Posted in computers | Tagged , , | Leave a comment

6502 breadboard computer: part 1

The first computer I ever used, probably in 1977, was my older brother’s KIM-1. This was a bare, single board computer that was really just a development kit for the 6502 microprocessor. It just had 6 numeric LED displays and a hexadecimal calculator-style keypad with some extra buttons for entering, modifying, running and stopping programs running.

You programmed it in machine code – hexadecimal numbers that represented instructions and data. Although time-consuming and difficult, programming the ‘bare metal’ in this way is a great grounding in computer science and coding: it gives you an appreciation of how programs and hardware interact, but more fundamentally, it helps you learn how very much can be achieved with a very limited set of instructions. If you can add, you can subtract, you can multiply and divide, and so on.

The 6502 went on to power the Apple ][, Commodore PET, Commodore 64, Nintendo Entertainment System as well as the Acorn System 1 and the BBC Micro. I soon made the switch from machine code to BASIC, but always hankered after my own KIM-1 or Acorn System 1 - indeed I wish I'd nagged my parents more to but me the latter now, it would have been a pretty good investment. Acorn became ARM, and now almost every human on the planet has one of their microprocessor designs in their pocket. The other thing that stuck with me, coding in BASIC on a PET or ZX Spectrum, was the blinding speed at which machine code routines ran, whether utilities to flip graphics slideshows or entire games.

I previously explored turning a BBC micro:bit into a simple CPU-like machine, but thought for my winter project I'd have a go at building my own breadboard computer, based on the modern version of the 6502, the Western Design Centre W65C02S.

There's quite a vogue for building simple breadboard computers from the ground up, and I can of course recommend Ben Eater's video guides, which I'm using as the basis for my project. I'll be diverging a bit from his path, and I thought it might be worth documenting some of the problems I had along the way. I also highly recommend this single video from Wifi Sheep, who only takes the very first steps but explains everything very well for the non-expert.

Goals

  • To learn a bit more about the electronics associated with computer hardware design
  • To learn some electronics, full stop
  • To re-learn some assembly language for the first time in 40 years
  • Maybe eventually to make something with a simple display, keyboard and monitor program that can be programmed like a KIM-1 or Acorn System 1

clock module

Starting with a clock

Making a clock seemed like a good place to start. I found Ben Eater’s clock a bit too advanced for my liking, and had originally intended just to have the option either to single-step the processor using a debounced button, or run it at the full 1MHz clock speed using a self-contained crystal oscillator IC.

In the end, I compromised a bit and built a clock using just two 555 timers which I can switch between single-step mode (using the 555 timer for debouncing) and a slow but variable mode which allows you to adjust the clock speed with a variable resistor. It’s basically the first two parts of the Ben Eater clock project, but I didn’t add the extra circuits to combine the logic, and I just added a simple single-pole / dual-throw switch to select which one I want to use. It’s not perfect, but it’s much simpler and more compact that Ben Eater’s, and I still learned a bit about 555 timers, and basic electronics with resistors and capacitors along the way.

Blinking lights!

It was now time to bite the bullet and connect up my modern 6502 processor. I ordered most of the bits Ben Eater uses from Mouser Electronics, and some other bits like the wire, LCD display and the EEPROM programmer from various suppliers in China. I guessed a bit, and time will tell whether I actually bought the right chips, I really didn’t have much clue what I was doing!

So, first step was to get some power to the processor, connect some LEDs across the address bus to see if it was alive and if my clock module worked. At first, I couldn’t get anything working at all. It turned out all the anti-static, anti-moisture packaging with its dire warnings had made me over-cautious. I just hadn’t pressed the pins of the CPU chip hard enough into the breadboard and they weren’t making contact.

first steps with the breadboard computer

I connected the pins of the W65C02 CPU like this:

w65c02s pinout

pin function notes
21 VSS GND for logic
8 VDD Main +5v power in
40 RESB Reset. Needs to be high to run; connects to 5v rail via a 1K resistor; connect a push button to GND rail as well.
38 SOB High, tie direct to 5v rail (set overflow)
2 RDY High, tie to high (+5v) via 1k resistor
4 IRQB High, tie direct to 5v rail (interrupt request)
6 NMIB High, tie direct to 5v rail (non-maskable interrupt)
36 BE High, tie direct to 5v rail (bus enable) – not connected in Wifi Sheep video

I connected some LEDs across the first few pins of the address bus (pins 9-14), powered both the clock and the CPU breadboard off an old USB lead which I chopped one end off and plugged into an old iPhone charger, and sure enough the LEDs on the address bus blinked madly.

Ordered blinking lights that count

That was quite exciting, but all a bit chaotic and meaningless. Following Ben Eater and Wifi Sheep I then hard-wired a NOP (no operation) instruction to the data bus. This means that the processor has an an instruction to follow, albeit one that does nothing, but it does mean you can see it scanning the address bus in some kind of logical order, and if you single-step the clock you’ll see that each NOP instruction takes two clock cycles to execute. I also added 16 LEDs across the whole address bus so I could see the whole bus being scanned.

full address bus LEDs

You need eight 1k ohm resistors for this. The NOP instruction’s hexadecimal code is EA, which is 11101010 in binary. Starting with pin 26, I connected them like this via 1K resistors

Pin     Connection
26  D7  +5v (1)
27  D6  +5v (1)
28  D5  +5v (1)
29  D4  GND (0)
30  D3  +5v (1)
31  D2  GND (0)
32  D1  +5v (1)
33  D0  GND (0)

Now you can single-step the 6502 through its initialisation sequence, and watch it then settle down to start scanning memory from location EA – and of course, as the single NOP instruction has been hard-wired across its data bus, this is the only instruction it can ever see, so it keeps on counting. It’s quite therapeutic watching the LEDs counting in binary, but next I need to run some real code, which means using some kind of assembler program and programming and adding some memory in the form of an EEPROM… what could possibly go wrong!?

Posted in computers, hardware | Tagged , , , | 2 Comments

Printing text on an LCD display using switches

There’s a YouTuber called the 8-Bit Guy who’s made a fantastic project where he gets text on an LCD display just using switches instead of a micro-controller or computer. He made his (video below) in a nice box with chunky switches, and I thought I’d try and make one on a breadboard.

This was a mistake, but I did, just about, get it to work and it makes an interesting project to learn a bit about low level logic, binary maths, data representation and so on with some very simple and inexpensive parts. It’s a good gateway to building a more complex project like a breadboard computer, which I plan to do this winter and it will use a display just like this so it’s all good practice.

Building it

Here’s what I used:

  • a 2 x 16 alphanumeric LCD display (old-fashioned parallel type, not one with an SPI interface)
  • 9 tiny single-pole dual-throw switches
  • a push-button
  • a 0.1uF capacitor to debounce the push-button
  • a variable resistor
  • a 4.7k ohm resistor
  • a breadboard
  • jumper wires
  • a USB lead with one end stripped to provide 5v power

Here’s how I wired it up – I’d be very happy to be corrected on my inevitable mistakes – I am not an electronics expert in any way!

LCD switch wiring diagram

The LCD pin wiring goes like this from left to right:

LCD pin
 1 GND
 2 +5v
 3 variable resistor for contrast
 4 centre pole of register select switch
 5 GND
 6 one side of the enter button
 7 to centre pole of data switch
 8 to centre pole of data switch
 9 to centre pole of data switch
10 to centre pole of data switch
11 to centre pole of data switch
12 to centre pole of data switch
13 to centre pole of data switch
14 to centre pole of data switch
15 +5v for backlight
16 GND for backlight

Using it

Switch the program select switch to the 0v / GND position and enter some control codes. I tried a few different ones but found that this (sometimes) worked to select two line mode. Put the data switches in each position, then press the ‘enter’ button:

0000 1111
0011 0000

Then to enter text, switch the program select switch to the +5v position, alter the switches to the positions of binary representations of ASCII characters, and press the enter button after each one.

H 0100 1000
E 0100 0101
L 0100 1100
L 0100 1100
O 0100 1111
  0010 0000 (space)
W 0101 0111
O 0100 1111
R 0101 0010
L 0100 1100
D 0100 0100

The little breadboard switches are far too fiddly and prone to flying out of the board, so if I were to make this properly I would go the same way as the 8-Bit Guy and use big switches in a proper box.

If you fancy connecting one of these to a BBC micro:bit, check out my previous post: http://www.suppertime.co.uk/blogmywiki/2019/04/lcd-microbit/

Related videos

The 8-Bit Guy video that started me making this:

A Ben Eater video on adding LCDs to a breadboard computer which has very useful stuff on the control codes:

Posted in computers, hardware | Tagged | Leave a comment