The serial port appears for a single second, and then vanishes before you can upload any code.
This has been happening to me with Pop OS, but apparently also happens with other Ubuntu variants. I can’t believe what the cause is, but if you check dmesg and you will possibly find the following occurring :
[ 98.044600] usb 3-2: New USB device found, idVendor=1a86, idProduct=7523, bcdDevice=81.33
[ 98.044606] usb 3-2: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[ 98.044607] usb 3-2: Product: USB Serial
[ 98.046052] ch341 3-2:1.0: ch341-uart converter detected
[ 98.046409] usb 3-2: ch341-uart converter now attached to ttyUSB0
[ 98.608979] input: BRLTTY 6.4 Linux Screen Driver Keyboard as /devices/virtual/input/input41
[ 98.887664] usb 3-2: usbfs: interface 0 claimed by ch341 while 'brltty' sets config #1
[ 98.888541] ch341-uart ttyUSB0: ch341-uart converter now disconnected from ttyUSB0
What we see happening is the OS finds the newly plugged in CH340 based serial device on your board and creates a new serial port, in my case, ttyUSB0. Excellent. But then, along comes “BRLTTY”. BRLTTY has decided it knows what this device is, removes the serial port and turns the device into an input / keyboard device. BRLTTY apparently knows best and claims all devices with the manufacturer / product ID of a USB to UART adapter chip, that is absolutely not always the product they think it is. This is really poor default behaviour, especially as this all happens silently. Apparently BRLTTY is accessibility software for the blind that is installed by default.
To solve the issue, assuming you’re not blind, simply type “sudo apt remove brltty” (without quotes) at the command line and it will be uninstalled, making the issue go away.
Not in Sync
The not in Sync error, where you get a repeated message such as the following :
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
… is an old one with many causes. One cause now seems to be that if you use a clone device, the Arduino IDE refuses to talk to it by default. The solution might be to change the “Processor” in the Tools menu to “ATmega328P (Old Bootloader)”. This would apply to boards such as Unos and Nanos. This might actually also apply to older genuine Arduino Boards.
As you might guess, I’ve had a slightly frustrating day. All I did was try to load a program into a clone board someone gave me the other day.
UPDATE 31st July 2024 – This post has been updated to reflect more recent versions of QEMU m68k as I was notified that the instructions I had followed were out of date. The 68k specific patches have more recently been integrated into the main build and so it is no longer necessary to use the q800.upstream branch I originally used.
UPDATE 1st November 2024 – Last night I was able to build and run 68k QEMU on an 64bit ARM based PineBook Pro running Manjaro Linux. Manjaro uses yum instead of apt, so grabbing software was different, but all I needed to do was update installed software, then I installed the repository’s copy of qemu-system-m68k (a lazy way of getting most dependencies), then I had to install the build environment ninja. After that, everything worked exactly as described below, although compiling took quite a while. I haven’t benchmarked the system, but it feels like it runs pretty well. Mac OS 8 didn’t take too long to install. Given this, I would expect this software to be happy compiling on other ARM based Linux PCs and SBCs, such as the Raspberry Pi.
QEMU m68k Running Mac OS 8.1 on Manjaro-ARM (click to view)
Introduction
I recently installed the 68k version of QEMU on Linux (Pop! OS) and struggled to find detailed step-by-step instructions by googling, so thought I’d upload some notes to help others. I suspect that part of what tripped me up is that previously, it was necessary to build from a branch and not the central source, which led me down the wrong path to to get the m68k variant of QEMU to build, but in truth building the main branch source now gets you to a working emulator (although not the copy in the Debian software repository). This is slightly muddied by the out of date threads that are returned as the primary results when you search for instructions on building QEMU for 68k on Linux.
Building m68k QEMU
My primary source for building qemu-system-m68k for Linux was here but ultimately I needed some guidance from a contributor to the project who saw my post and got in touch to point me in the right direction. I’m very appreciative of the time they took to help me on my way. This assumes you plan to run Classic Mac OS (between 7.1 and 8.1), and not AUX or anything more exotic.
Navigate to your home folder
> sudo apt update
> sudo apt-get build-dep qemu-system-misc ninja
> git clone https://gitlab.com/qemu-project/qemu.git
> cd qemu
> ./configure --target-list=m68k-softmmu --enable-gtk --enable-sdl --enable-slirp
> make -j4
I then copied the executables qemu-system-m68k and qemu-img from the build folder, into the folder I wanted to run them from.
Creating / Getting the Required Files
To run, you will need to generate two disk images, and a copy of the Quadra 800 ROM. Place the ROM in the same folder as the executables, and name it Quadra800.rom. I next used some of the instructions from here to work out how to generate the needed image files as follows. Run these two commands in the location you placed qemu-system-m68k and qemu-img previously.
> qemu-img create -f raw -o size=1G mainDisk.img
> qemu-img create -f raw pram-macos.img 256b
On the first line, change “1G” to other values to change the image size from this example of 1 gigabyte.
Launching the Emulator for the First Time
The emulator “captures” the mouse (and keyboard) once you click in the window. To free the mouse, press Ctrl+Alt+g.
To initially format the disk image, you can use Drive Setup (Mac OS 8.x) or Apple HD SC Setup (7.6.1 and older) while booted from the OS installer CD. It is critical that the CD iso image you use has been properly created and includes the driver partitions and is bootable, otherwise you will just get a flashing question mark on a floppy disk icon. If you do not already have an image, you can grab one from the Macintosh Garden here (which is a direct link to download #6 (at time of writing) on this page), or from my own site here.
Rename the iso image as MacOS81.iso and place it in the same folder as qemu-system-m68k and qemu-img.
If you plan to run another version of Mac OS on the emulated computer, download a bootable iso image of that operating system, for example Mac OS 7.6.1, place it in the same folder and name it, for example, MacOS761.iso. In the following instructions I will assume that you are using a, 8.1 CD image to format the disk and install the operating system. If you plan to install another OS, use that disk image instead.
Boot the emulator from the Mac OS 8.1 CD image using the following command, all on one line :
When you press return, you should get a QEMU window, hear your emulated Mac chime and see the boot process. Once the emulated computer reaches the desktop, open the CD, open the Utilities folder and then launch the Drive Setup application. If you are formatting the emulated hard disk using Mac OS 7.6.1 or older, skip to the section titled “Apple HD SC Setup” and then return to the section titled “Here”.
In Drive Setup, select the unformatted hard disk from the list, click the Initialize button, and then in the Initialize dialog box, click the Custom Setup… button, select “1 Partition” from the Partitioning Scheme popup menu, ensure the other popup menu says “Mac OS Standard” and not “Mac OS Extended” (if you plan to use the hard disk image with Mac OS 7.x), click OK, and lastly click Initialize. Once this is done, you can quit out of Drive Setup, and rename the hard disk you just formatted if you haven’t already. “Macintosh HD” is traditional. Once you’re done, you can install your operating system.
Here
To install an OS, navigate to the desktop. If you have just booted you will be there by default, otherwise if you are following these instructions and have just formatted your “hard disk” you may need to quit out of the formatting utility and close some Finder windows. Once you get to the desktop, open the CD and run the main installer application. Follow on-screen instructions to complete the install. If you’re unfamiliar with the process, the default settings should be just fine. Selecting Restart (if offered in a dialog box, or from the Special menu at the desktop) should bring you back up in your installed copy of Mac OS.
You can shutdown the emulated computer by selecting Shutdown from the Special menu while at the desktop.
If you wish to start QEMU again, but from a different CD image, for example a Mac OS 7.6.1 iso image we downloaded and called MacOS761.iso, enter and execute the following command, which is identical to the previous command, except the CD Image filename has been updated.
Once you’re done, Shutdown and we’ll set up a simpler (less typing intensive) way of launching the emulator, as well as consider a couple of helpful customisations.
Create and edit a new bash script in the folder with qemu-syetem-m68k…
On the first line “-g 1152x870x8″ sets the display to 1152 by 870 pixels (Apple’s 21” monitor resolution) at 256 colours (8bit). If you want to run the display at 640 by 480, or 800 by 600 at 24bit colour, delete the “-g 1152x870x8” text (move the cursor with the cursor keys in nano. The default display mode allows you to switch between 640×480 and 800×600 from the Monitors control panel within the emulated computer.
If your host computer has an optical drive, the last two lines set up the emulator to directly access disks put in that drive. If you do not have an optical drive, you may need to delete these last two lines.
Press Ctrl-x and when prompted, press “y” to exit and save changes.
Now, when you want to launch the emulator, you can run the bash script launch68k.sh, for example by navigating in the terminal to the folder, and then typing ./launch68k.sh.
Apple HD SC Setup
If you format the emulated hard disk using a Mac OS 7.6.1 or older version of System 7, you will need to use the formatting utility Apple HD SC Setup. This is because older versions of Drive Setup were exclusively for PowerPCs and / or formatting IDE hard disks (and we’re emulating a SCSI disk). While the process is pretty simple, an quirk I noticed while setting up my emulator was that Apple HD SC Setup only created a very small data partition on the emulated hard disk. This is simple to fix though.
Step 1
Launch Apple HD SC Setup, likely in the Utilities folder on the top level of the CD you have booted from. Select the SCSI ID of the emulated hard disk you want to format by clicking the Drive button, you most likely want “SCSI Device: 0”. Do not get this wrong or you could erase the data on whatever hard disk image you have mounted in your emulator.
Step 2
Click the Initialize button and wait. This takes quite a while.
Step 3
Click the Partition button, then click on the Customize button if available.
Step 4
If the disk utilisation graphic shows partitions taking up most of the disk, you’re good to quit out of the utility, but if like me, the data partition is only using a small portion of the disk and the remainder is grey half tone, select the partition and click remove.
Click towards the bottom of the grey area. In the dialog box that appears, select the option “Mac Volume” on the left, and then in the text field on the right hand side, enter a value (in K) that is about 1000 less than the maximum value quoted below the text field. Click OK once you’re happy. You should now have a small amount of grey between the disk driver and the data partition. Click Done.
Step 5
Quit Apple HD SC Setup and return to the heading “Hear” above, to install the operating system.
Getting Software onto the Emulator
At this point, if you have an optical drive, you should be able to install any software you own on original CDs. This only gets you so far though. I’ve actually been moving files onto the disk image using another emulator. Basilisk II allows access to the host file system and while QEMU isn’t compatible with my Basilisk II disk images, the QEMU image works fine in Basilisk II. Other emulators might also work in this fashion, such as the Infinite Mac website, SheepShaver and others.
Make sure you don’t accidentally launch both emulators at the same time or you will possibly cause issues and corruption.
Limiting Processor Usage
On my fairly elderly laptop, when I run QEMU it consumes 100% of two cores (from the OSes perspective, as hyperthreading is on this isn’t strictly correct). This is enough to either cause the fan to ramp up to an annoying level, or if I am running from the battery, significantly reduce battery life.
The truth is, I don’t actually offer all of the speed this offers me, so I decided to look into how I might best throttle the performance of m68k QEMU to reduce the CPU time it consumes at the cost of emulator performance. Ultimately, I settled on using the program cputool which I had to install, but was available from the Debian repositories so a simple apt get install cputool sorted that.
This solution isn’t perfect as it makes the emulated graphics redraw stuttery, but it is OK if you’re mainly typing and not playing games or drawing.
After installing cputool, I was able to make a new script to launch QEMU, that just called my existing script. What I ended up with was a bash script containing…
cputool -c 50 -- ./startqemu.sh
Where “startqemu.sh” was my existing start script, “50” is the percent of each core’s total time I’m allowing. QEMU m68k uses two threads, so with this setup, I see the total CPU usage by the emulator halved and visible as 50% usage on two cores.
The above method should probably work with other emulators that consume all of an available core or core’s resources regardless of whether it is needed or not.
Advantages and Disadvantages
I’m pretty pleased with this emulator, with the only slight disadvantages I’ve seen so far (since installing an up to date version) are that it runs slower than some other emulators, it is harder to install and transferring files between the host and emulator isn’t as trivial as in emulators that mount the host file system on the desktop by default. This plays off against much better stability and compatibility when compared to Basilisk II for example, which I have been mainly using lately. One big compatibility improvement is sound. For example, SoundEdit 16 was not usable on Basilisk II due to constant crashes.
The driving factor for me trying QEMU was a bug that manifests in Basilisk II when writing software in REALbasic – if I convert an integer into a string in my REALbasic program, I get an incorrect result. This does not happen on real hardware such as my Centris 650 or my PowerBook G3, and also does not happen in QEMU.
Further Work
At this point, I should probably look into better ways of transferring files into the emulator. I believe that network filesharing, either using netatalk or possibly FTP, would be a fairly simple thing to setup. I’ve not looked into mounting the host system within the emulated Mac, I’m told this is possible, and will add instructions here when I look into it.
Obsolete Comments
This post was originally made with respect to an older, unofficial, build of QEMU with which I had a number of issues. I’ve moved the old list of issues here so that if someone is searching for terms they contain, they will still find this guide.
Issues (some minor) I experienced with the development branch and thread detailing how to build on Linux…
Build instructions don’t mention all dependencies.
Could not run configure due to permission issues if you try in a location outside your home folder, specifically on a secondary partition in my instance (I haven’t tried this again with the latest source).
The emulator is debouncing double clicks on my computer so they only count as a single click. It is not possible to double click in the normal manner. -fixed-
Disk image compatibility is very picky and the emulator does not seem to work with existing disk images.
After generating a disk image using QEMU’s own tool, it will not format, or even show on the emulated SCSI bus in Mac OS until you format it in Mac OS 8.1. -fixed-
The man pages are exclusively about x86 PCs even when called in relation to the m68k executable.
Resolution support is limited, more limited than real hardware.
The SDL mode does not work on my computer and just results in a blank screen.
Installing from the Debian repositories results in a non-working executable.
The most frustrating of these issues have been entirely fixed in the newer version of qemu-system-m68k, although some of the minor issues are still present (and others I haven’t re-checked for at this point). I have marked items I’ve tested and found solved as “-fixed-“.
Creating a Disc Image of a Classic Mac OS Bootable CD
The most important thing when making bootable disc images is to test them. After you create your disc image file and before you upload it anywhere, make sure you burn it back to a CD and test it On Real Hardware. If you do not have an appropriate vintage computer, speak to a friend that does. There are so many mistakes that it is possible to make that in a recent review, approximately one third of images uploaded to an archive page had been rendered un-bootable in some way. While testing takes a little time, it is nothing compared to the time a bad image wastes for dozens of users downloading it, to say nothing of the frustration it causes new users who may not have the experience to realise what the issue is.
NOTE – If your source CD contains true multimedia (for example, data and CD Audio, like many game CDs from the 90s), you very likely will need to create a bin + cue image of the source. I’m aware that a lot of people don’t like these, but sadly, there is no alternative that I know of. Genuinely, bin+cue isn’t a superfluous format designed to annoy you, it has a specific purpose and some CDs can not be properly burnt to new discs without it.
Classic Mac OS
Toast
Warning, this method likely very slightly modifies the CD, but other methods, using other options within Toast, will significantly modify the original content of the CD, rendering them less useful or even unbootable on any system, so this is the best you’re going to get! Do not use the “Mac Volume” option!
Launch a copy of Toast in Classic Mac OS, I’m using Toast 4.1.3, running on Mac OS 7.5.5 as an example.
Select “Disc Copy” as the operation type in the window. Then click the “Data…” button and select the disc you want to copy.
From the File Menu, select “Save as Disc Image…”. Save the file, conventionally as a “.toast”, but this file can actually be treated as a “.iso” file by many good CD burning programs.
Current macOS
NOTE – You will need an external optical drive as recent Macs do not come with a built in optical drive.
With a GUI
Disk Utility
Warning, this method likely very slightly modifies the CD. If a better alternative method is known, please propose it and I will add it here.
Launch Disk Utility, select the disc (not the partition – you must select the top level of the device you are trying to copy). Then select “Image From <device name>…” from the File menu.
Under the “Format” popup menu, select “DVD/CD Master” and ensure that no encryption is applied. Navigate to where you want to save, enter an appropriate file name and click save.
The resultant “.cdr” file can actually be treated as an “.iso” and can be renamed and burnt with many good CD burning programs.
AARU
I am not familiar with this software, but it can apparently also produce a good disc image.
To save a disc image of your CD to your desktop, first you need to work out what the Operating System calls your CD Drive. To do this, launch Disk Utility, and click on the optical drive top level.
This will display some information about the drive, including, as shown above, in the lower right hand corner “Device”, which is in the example given “disk2”. This is your Device Name.
Alternatively, this information can be obtained by typing “diskutil list” (without the quotation marks) and pressing enter in a Terminal window and identifying the optical drive by its description. There will usually be an entry for “disk#” where # is a number, and then a number of additional entries with the same name, followed by “s#”, again where # is a number. Each of these additional entries are partitions on the disk. What we want is the top level name, so the one in the format “disk#”. This is your Device Name.
In a Terminal window, type “cd ~/Desktop” (without the quotation marks) and press enter. This will change the current directory to the desktop folder of the current user. Then, very carefully (making sure that there isn’t already a file called “cdimage.iso” on your desktop – if there is, you can change the filename in the following command (it is generally best to avoid spaces to keep things simple)), using the Device Name obtained above in place of the text “<disk#>”, enter the following command :
dd if=/dev/<disk#> of=./cdimage.iso bs=2048
This command will copy the “if” (input file) to the “of” (output file) with a “bs” (block size) of 2048 bytes. This should give us a nice pure and unadulterated disc image of the CD.
dumptoiso
I’ve not tested this script, but the following has been designed to simplify the process with dd :
In older versions of Mac OS X, it is possible to use methods similar to the “Toast” instructions given for Classic Mac OS, or for “Disk Utility” for current macOS, with minor interface differences.
Command line instructions remain effectively identical to current macOS instructions above when using dd in older versions of Mac OS X.
dumptoiso, linked above, also works back to 10.3, if not earlier.
Linux
With a GUI
Install the application “K3b”.
Launch and select the “Copy Medium…” option from the “Tools” menu.
Verify the correct drive is selected in the “Source Medium” popup menu, make sure “Copy Mode” is set to “Normal Copy”, and check the “Only create image” checkbox.
Switch to the “Image” tab and enter a filename and path.
Click “Start”.
You should now have a disc image of your CD saved at the location you selected. When burning Mac HFS images from K3b it will complain that it does not recognise the format. Don’t worry, just dismiss the dialogue box and continue.
With the Command Line
To save a disc image of your CD to your desktop, first you need to work out what the Operating System calls your CD Drive. To do this, you can launch you disk management application such as gparted or “Disks”.
This will display some information about the optical drive, including the “Device” path, which on my computer is “/dev/sr0”. This varies more on linux than on other platforms, depending on the flavour of linux you run. This is your Device Name.
Alternatively, this information can be obtained by typing “df -h” (without the quotation marks) and pressing enter in a Terminal window and identifying the optical drive by its description. If there are multiple partitions mounted, what we want is the top level name. This is your Device Name.
In a Terminal window, navigate to the location you want to save your disc image. Then, very carefully (making sure that there isn’t already a file called “cdimage.iso” at the location – if there is, you can change the filename in the following command), using the Device Name obtained above in place of the text “<device>”, enter the following command :
dd if=/dev/<device> of=./cdimage.iso bs=2048
This command will copy the “if” (input file) to the “of” (output file) with a “bs” (block size) of 2048 bytes. This should give us a nice pure and unadulterated disc image of the CD.
Windows
ImgBurn
After installing ImgBurn, launch the application and select “Create Image file from Disc”.
Insert the disc you want to copy and select a destination.
Click on the CD to file pictograph / button (that doesn’t look one bit like a button, and shown below for clarity) and ImgBurn will create your disc image.
The display will change to show progress and a message appears on screen once the process has completed.
Creating a Custom Bootable Classic Mac OS CD from Linux
and possibly other operating systems, which I don’t have to hand
The following is a description of the process to easily create a HFS formatted disk image and burn it to a CD, suitable for use in a Macintosh computer running Mac OS 9.2.2 or older, assuming it has an operable CD drive. If your CD drive is struggling to read disks, cleaning its lens can help. I have some short instructions on how to do that here.
The instructions on actually generating an appropriately formatted ISO disk image ready to be burnt to a CD are universal, and apply equally to Linux, modern Mac OS and Windows, but these instructions provide Linux specific detail as it is the only OS I have on hand to test.
What You Will Need
Hardware
A computer running Linux (or another OS, but most of my guidance wont be directly applicable)
An optical drive capable of burning CDs
A blank CD-R
A vintage Macintosh running a version of the classic Mac OS, with a functional CD drive.
Software
A flavour of Linux, this page assumes a Debian family variant, such as Debian, Ubuntu, Mint or Pop!_OS (other operating systems can be used, but detailed instructions are not provided)
Basilisk II – a cross-platform Macintosh Emulator, a bootable disk image with required software (provided below)
A ROM image for the emulator, taken from a retro Macintosh you own, or at least equivalent to a machine you own.
K3b – CD burning software for Linux (other software may work, but detailed instructions are not provided))
Setting Up the Software
Installation
To install Basilisk II, run the command in a terminal…
sudo apt install basilisk2
To install K3b, run the command in a terminal…
sudo apt install k3b
Download this disk image which will be your main boot disk for the Basilisk II emulator, extract the contents from the ZIP and store it in a convenient location.
Obtain the required Macintosh ROM, from a Macintosh II series or Centris / Quadra ideally, but other ROMs are likely to work. I have been using a IIci ROM. Store it in a convenient location.
First Run of Basilisk II
01 Volumes
After launching Basilisk II, you will be faced with the window shown above, without the two disks listed. To add these, first, click the “Add…” button, navigate to where you stored the disk image “Bernie.dsk” and select it. This already contains an operating system and the retro Mac software we’ll need to create a bootable CD. “WorkingVolume.dsk” is a second, empty, disk image that we will create now and which will be where we will collate and organise the CD we want to build. Click the “Create…” button and enter the following details for Size and the file name. Navigate to a convenient location to save, and then click “OK”. We now have a 650MB empty disk image in addition to our 1GB, bootable, disk image.
02 Creating Working Volume
Within the “Graphics/Sound” tab I set the Width and Height to 640 and 480 respectively. These values suit me, but are not critical – for example you could set 1024 and 768 if you wanted a larger emulated display. Sound settings can be left at your installation’s defaults. In the “Memory/Misc” I set MacOS RAM Size to 32MB, Mac Model ID to Mac IIci, CPU Type to 68030 with FPU and selected a IIci ROM file using the “Browse…” button. With my setup, it was required that I selected “68030 with FPU” and not just “68030”, otherwise the emulated computer would not boot from my particular operating system.
03 Graphics / Sound
04 Memory / Misc
Once you are happy, you can click the “Start” button, and you should be greeted with an emulated Macintosh booting very quickly. Once the startup sequence has completed, the first time only, you will be greeted by a dialogue box asking for you to format the empty “WorkingVolume”, 650MB disk image that you created. Name this disk whatever you want your CD to be called when it mounts on the desktop (after this first time, you will need to do this by renaming the volume on the desktop). Keep the format as the default “Macintosh 650 MB”. Click “Initialize”.
05 Format Working Volume
The new volume, in my instance called “WorkingVolume” will mount on the emulated desktop, along with “Bernie”, our boot volume and “Unix”. Unix is a link into the host computer’s file system which we will be using later to transfer our complete disk image back to the host for burning to a disk. Your window should look similar to the following.
06 Booted Bernie
Congratulations! You are now ready to start creating your custom bootable CD!
Creating Your Bootable CD
Use the emulator to fetch the various files you want to put on the CD. If you are on a computer that doesn’t natively support resource forks, such as Linux or a Windows PC, it is best to move any files onto the emulator in a protective container format such as a .bin file, later versions of .sit (SIT5) or some disk image formats. Some disk images can be “added” to the emulator as other emulated hard disks in the same way we added the “Bernie” disk above. Care must be taken as classic Mac OS files contain both a data and a resource fork. The resource fork is not usually recognised by other computer platforms and they are prone to “strip” the resource fork from a file. Doing so severely corrupts most Mac OS files, for example, 68k applications have all of their executable code in the resource fork and removing it… removes the application’s ability to do anything at all, irreparably. Assuming the files you are working with were correctly prepared in the first place (this is sadly more frequently an issue than it should be), extracting the archives / encoded files from within classic Mac OS itself is usually the best, although not only, solution.
Personally, I store files I want to transfer to the emulator in a specific folder on my hard disk, then use the “Unix” volume within the emulator to copy them over to the volume “Bernie”. Here, I extract them (the tools provided within “Utilities” should help in many cases) and then copy the files onto “WorkingVolume”, and arrange them as I want. Note that the window arrangement you leave the windows in will be burned forever into the CD, so it is usually good to move windows up to the top left corner to ensure that they are easily accessible even on a computer with a small screen. In the following example, I have copied a number of items from the “Bernie” disk over to “WorkingVolume”. This includes the System Folder, as this will be the bootable operating system on my CD. This System Folder is a good starting point for bootable disks as it is a universal “minimal install for any computer”, although older computers, such as non-32 bit machines like the SE/30, are not compatible with Mac OS 7.6.1 by default.
07 Setting Up a CD
Once you are happy with the contents, icon layout, window positioning and have verified that everything you have placed on the disk works as expected, you are ready to start creating a CD disk image. To do this, open the “Toast Deluxe 4.1.3” folder on the Bernie disk. Then launch the application “Toast Deluxe 4.1.3”. You should see a window similar to the one shown in the second image immediately below. Select “Mac Volume” from the drop down menu, and then drag the “WorkingVolume” disk icon (or whatever you have called your working volume) into the area under the drop down menu. The window should update to similar to the provided image, with the name of your volume following the bold text says “Data: “. Note that Toast will use the CD ROM or CD DVD ROM Extension from the booted Operating System as the CD Driver on the CD it writes, so it needs to be made certain that a version is used which is compatible with the computer you plan to boot. In some cases it might be best to create the custom disk image on the actual machine itself if possible.
08 Toast Folder
09 Mac Volume
Click the button “Data…” and verify that the “Bootable” checkbox is checked if you intend to create a bootable disk. If you do not intend your disk to be bootable, you do not need to do this step. Click “OK” to close this dialogue box again.
10 Select Volume
As per the following two images, select “Save as Disc Image…” from the “File” menu, and enter a name for your disk image. Note that you will want to finish the file name with “.iso” – this is important for other operating systems, such as windows, but also serves as a reminder when you are managing your files. You can either save the file on “Bernie” if there is 650MB free, or alternatively save directly to the host by navigating to a suitable location on the mounted “Unix” volume.
11 Save as Disk Image
12 Save Disk ISO
Congratulations! You now have a disk image, hopefully formatted correctly to boot a classic Macintosh computer!
Burning the Disk Image
01 K3b Screen
On Linux, launch K3b (which you installed at the beginning of these instructions) and select “Burn Image…” from the “Tools” menu. Near the top of the window under the text “Image to Burn”, to the right of the combo box, is a small button with a folder icon. Click this to use a file open dialogue box to select the CD disk image, in my case “WorkingVolume.iso”, which you intend to burn to a CD. When you select the disk image, you will get an error dialogue box as shown below in the second of the three images – Click “Yes”. This dialogue box is generated because the software doesn’t recognise the format of the disk image, because it is a classic Mac OS disk.
02 Select Working Volume ISO to Burn
03 Are You Sure Not Recognisable
04 Ready To Burn
At this point, it is probably a good idea to insert a blank CD-R into your optical drive if you haven’t already. Once the computer has finished probing the disk and the window updates, in the “Burn Image – K3b” window, set “Speed” to the lowest speed offered and click “Start”.
05 Burning
06 Burn Complete
Once the computer has finished burning the disk, it should automatically eject, and you are ready to test it in your retro Mac. Pop it in the Mac’s drive and boot while holding the ‘C’ key to tell the computer to boot from the CD, assuming that the CD drive supports booting and the computer is compatible with the system software you used!
As
a child I had an interest in electronics. I took options at school
which taught me the basics, but found that a few small details were
omitted which made it slightly more difficult to move from theory to
practice. Following a recent discussion with my brother about how we
thought it would be best to introduce electronics to a beginner and
move through to designing and building your own circuits, I decided
to write something to hopefully help other people in the same
position as my 15 year old self.
Useful
Parts for the Following
74HC00 – Quad 2-input NAND gate
74HC04 – Hex inverter gate (NOT)
74HC32 – Quad 2-input OR gate
74HC08 – Quad 2-input AND gate
2N7000 – MOSFET
Pushbutton
LED
220R Resistor
Breadboard
Power source?
Basic
Boolean Logic
As
a tool for introducing electronics in more general terms, I’m going
to introduce logic and logic chips. In electronics, logic is usually
based on the theory of using voltages to represent two states, “TRUE”
or “FALSE”, sometimes called “HIGH” and “LOW” (in
reference to the voltage). When the voltage is high, and the signal
is considered to be present, this is a TRUE. Multiple TRUE and FALSE
signals can be used together representing a set of inputs to be
analysed to give specific outcomes in specific input scenarios by
applying various logic operations. Even
with basic logic rules, complex systems can be built.
The three most basic logic operations commonly seen in electronics are “AND”, “OR” and “NOT”. These are implemented physically as “gates” (e.g. “you need an AND Gate in your circuit”), which it is common to find several of in one microchip. The most conceptually simple gate is the NOT gate, which takes an input signal, and inverts it before outputting it. This means that when applying a logic TRUE to a NOT gate, it will produce a logic FALSE at the output pin and vice versa. The OR gate provides a logic TRUE when either one, the other, or both of its inputs are TRUE. Finally, the AND gate produces a logic TRUE only when both inputs are TRUE. Any time the output is not TRUE for any of these gates, it will be FALSE. The following table shows all combinations for two inputs named Input A and Input B. It is possible to have AND and OR gates with more inputs, although the same result can be achieved by using multiple gates consecutively and feeding the output of one into the input of another. Note that as shown in the following table, the NOT gate has a single input. Within the table, the NOT gate has been assumed to be connected to Input A (and duplicate second rows have been omitted for clarity).
Input A
Input B
AND
OR
NOT
FALSE
FALSE
FALSE
FALSE
TRUE
FALSE
TRUE
FALSE
TRUE
TRUE
FALSE
FALSE
TRUE
FALSE
TRUE
TRUE
TRUE
TRUE
Equivalent
Circuits
The
various logic circuits can be considered as behaving in a similar
manner to the following conventional electrical equivalents. These
equivalents use switches to achieve the same behaviour, where the
bulb represents the output.
AND – Two Switches in a Row
OR – Two Switches in Parallel
NOT – A switch in Parallel with the Load
When
the switch is pressed, the load is bypassed as the path of least
resistance is through the closed switch. This means that when
the switch is closed (TRUE), the
LED is off (FALSE) and
vice versa. The resistor
R1 is included so that the switch is not a dead short over the
battery. The battery voltage was increased to 5V to make the circuit
more realistic in that the LED would be dim (or
go out) if the 2V supply
from the two previous circuits was used.
If you are unsure why this circuit acts as a NOT, consider that the resistance of a typical 10cm wire and switch might be 0.0005 ohm. Current follows alternative paths inversely proportionally to the resistance. If two paths are of equal resistance, the current will divide equally between both routes. If one resistance is 10 time greater than the other, 10 times more current will flow through the LOWER resistance path. As the LED has an effective resistance tens of thousands of times greater than the wire (if not more) effectively all the available current will go through the wire and switch rather than the LED. When the switch is released (goes open) the resistance of that path becomes huge (it might as well be infinite) and so all available current goes through the LED as it is now the path of least resistance. Much more detail can be given regarding how the resistance of an LED changes depending on voltage, about the resistance of the circuit and about the resistance of individual parts of the circuit etc. but very quickly this gets too detailed and distracts from the purpose of this example!
Just Draft Notes from here on in. Also, check that a 1k resistor is suitable for the circuit I drew. OK – I’ve checked the 1k and it looks OK (but I’d prefer to test the circuit) It results in less than 1.4mA current in the LED and not more than 5mA into the Base? something like that. A bigger resistor might be better, say 2 or even 3k.
Using Transistors Instead of Switches
There are two main types of Transistors, NPN and PNP. Effectively, the NPN produces switches on when a current is provided to the Base pin, while a PNP switches off when a current is provided to the Base pin. I remember the difference between the two symbols by telling myself that NPN stands for “Not Pointing iN”, with reference to the arrow in the symbol. The two symbols are as follows.
AND – Using Two NPN Transistors
In the preceding example the Base pins on the transistors are shown with the Base pins protected by 1k current limiting resistors (R1 and R2). In a real application, these inputs would be connected to something like the output pins of a microcontroller. The LED is also in line with a 220R current limiting resistor. To implement this circuit, you might use the common BC547 NPN transistor. This would be suitable for use with, for example, a 5V Arduino Uno. The following schematic shows how this might be implemented. Similar methods can be used for the OR and NOT implementations which follow, but this post does not go into detail regarding using transistors as the primary intention is to explain the use of Logic chips. I might return to the subject of transistors at a later date.
OR – Using NPN Transistors
Supplying current to either (or both) Input A or B will provide a current path from the LED to ground, completing the circuit and implementing our OR logic.
NOT – Using a PNP Transistor
To implement the NOT logic using a transistor, the easiest solution is to use a PNP transistor instead of the NPN used in the previous two examples. As noted, this type of transistor closes when current is provided to the Base. Note the different location of the arrow within the transistor’s symbol. The common PNP equivalent of the BC547 is the BC557.
In reality, within integrated circuits, the logic implementations are more complex to allow greater flexibility and a more well rounded product. The following is an extract from a Texas Instruments datasheet for the 7408, showing the individual transistors within each gate of the logic chip. The design is beyond me… especially as I’ve never seen a transistor with 4 legs.
Additionally, it is also possible to implement logic using “Relay Logic”, but that is a topic for another day.
Symbols
The symbols for the AND, OR and NOT gates are shown above. Note the small dot on the NOT gate – without the dot the triangular symbol would represent a buffer, which does not modify the output logic and simply passes the input signal to the output. The dot symbolises that the output should be inverted. This dot can be also added to other gates to mean that the output should be inverted. In the case of the AND and OR gates, this produces the NAND and NOR gates.
Note that schematics within this post were drawn using Fritzing – a free circuit designing program for Linux, MacOS and Windows.
This page is a DRAFT as I do not currently have the correct hardware to fully test and debug the process. Feedback welcome, but do not rely on this being correct!
The Economatics Smart Box serial interface boxes used to come with a program called “Smart Move”. The software appears to have been available for a number of platforms (BBC Micro, RISCOS, MacOS and DOS), but I have only seen copies of the DOS software while searching. The software appears to load machine code directly into the memory of the Smart Box rather than sending serial commands. This is interesting as it goes some way to overcoming the speed limitations of the 9600 baud serial connection.
The following details my experiments in trying to get the DOS version of Smart Move running on a modern Linux computer, although most of the detail should also be applicable to other modern OSes. Note that the original DOS software will no longer natively run on Windows.
Step 1 – Get DOSBox
On Linux, DOSBox is installed from you packet manager of choice. If you’re using a Debian / Ubuntu style setup, you can just type “sudo apt install dosbox” at the command line.
Step 2 – Finding the Serial Port
If you don’t have a built in serial port (not many people do these days), you’ll need a USB to RS232 adapter. There are really cheap ones available, but just to warn you – I’ve been through two of the cheap ones that have a silver cable and blue plugs. I’d advise spending double the money and getting something that will last. I have one of these, which seems to be marginally better made.
On Linux, run the command “ls /dev/tty*” – this will list all available terminals (including serial ports). Now plug in your USB adapter, and run the same command again… an extra file should have appeared. This is your serial port. In my case, it is called “/dev/ttyUSB0”. If you’re using Windows, you’ll need to work out what COM port the device is connected as. Past experience on Windows says that sometimes you need to keep plugging into the same USB port to get the same COM port between sessions, but this might just be a permissions thing at work. On MacOS, the process for finding the name of the serial port is basically identical, except that the name of the port is usually a little bit different under MacOS.
Step 3 – Configuring DOSBox for Serial
Now that you have written down the exact name of your serial port (either something like “/dev/ttyUSB0” for Linux/MacOS, or “COM9” for Windows), open the DOSBox configuration file. On Linux, mine was located in “~/.doxbox/” and was called “dosbox-0.74-3.conf”. I opened it in nano to edit it by running “nano ~/.dosbox/dosbox-0.74-3.conf”.
Note that a foldername starting with “.” is an invisible folder on Linux. Additionally, it looks like the config file name will change depending on the version you have installed. The fastest way to open the file on Linux will be to type “nano ~/.dosbox/*.conf” and then press enter.
Details of where to find the config file on other platforms can be found here.
Within the now open config file, find the section titled “[serial]”. This can be done in nano by pressing “Ctrl-w”, typing “serial” and pressing enter. There are a load of examples / explanation lines which start with the “#” symbol indicating that they are comments. Scroll past these to where there are (in my file) for lines, each starting with “serial” and then a number. Modify the first of these lines, which starts with “serial1” to the following, substituting your own serial port (note on Linux, you do not need the “/dev/” as shown) :
The following two downloads are the Smat Move DOS software for the Economatic Smart Box (“SmartV1-6”) and a DOS serial driver (“adf_150”). Both are needed to connect to the Smart Box.
The Smart Move software has kindly been made available here : http://flaxcottage.com/Oddments/default.asp – I have removed the “Finder.dat” file as this is a file added by MacOS and is not needed.
Extract the SmartV1-6 archive as a folder and store in a convenient location. You should now have a folder containing “SMART.EXE” and “AL.COD”. Create an additional folder called “Driver” within this first folder, and extract the contents of adf_150 into this folder.
Within the “Driver” folder, find the file “ADFCOM1.BAT”. Copy it, and name the copy “SBCOM1.BAT”. Open the file in a text editor. The contents should like like this :
@echo off
rem
rem Loading ADF for COM1
rem
rem ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄCOM-port number, COM1-COM127.
rem ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄAddress in hex of COM-port, 0-FFFF.
rem ³ ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄIRQ number of COM-port, 0-15.
rem ³ ³ ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄLocked baud-rate, 1-115200.
rem ³ ³ ³ ³ ÚÄÄÄÄÄÄÄÄÄÄSize of receive buffer, 256-16384.
rem ³ ³ ³ ³ ³ ÚÄÄÄÄSize of transmit buffer, 256-16384.
rem ³ ³ ³ ³ ³ ³ ÚÄReceiver FIFO trigger level, 1, 4, 8, 14.
rem ³ ³ ³ ³ ³ ³ ³
adf COM1 3F8 4 57600 8192 8192 8
rem ³ ³
rem ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³
rem ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÙ Advanced options:
rem ³ ³
rem 8192,7168,6144 16650,16,8 3 11
rem ³ ³ ³ ³ ³ ³
rem ³ ³ ³ ³ ³ ÀÄ Modem Control Register.
rem ³ ³ ³ ³ ÀÄÄÄÄÄ Line Control Register.
rem ³ ³ ³ ÀÄÄÄÄÄÄÄÄÄÄ 16650 Transmit FIFO trigger level:
rem ³ ³ ³ 8, 16, 24 or 30.
rem ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄ 16650 Receive FIFO trigger level:
rem ³ ³ 8, 16, 24 or 28.
rem ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Flow control continue or restart.
rem ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Flow control hold or stop.
rem
Edit the line “adf COM1 3F8 4 57600 8192 8192 8”, replacing the number “57600” with “9600”. This is the serial baud rate (the speed of the connection). 57600 baud is way too fast for the Smart Box, which runs at 9600 baud. Save the changes and close the file.
As an aside, 9600 is 9600 bytes per second, plus one stop bit. If I remember correctly about this, this means that 9 bits are sent for every 8 bits of data, which is why technical people get irritated when you say 9600 bits/second instead of baud.
Run the Software
With the USB serial adapter connected, the Smart Box connected and the Smart Box powered on, launch DOSBox in the folder containing “SMART.EXE” (but don’t actually use it to run any specific program, we just want it to open at the command line). On linux this is done by navigating to the folder you want to start in in the terminal, then running “dosbox ./”. I can only assume it is the same under Windows, but I do not have any way of testing. Windows user can get a command line by typing “cmd” straight after opening the Start menu, and then pressing enter.
At the DOSBox command line, enter “cd DRIVER” to move into the Driver folder. Then enter “SBCOM1.BAT” to run the serial driver setup script we modified with a 9600 baud rate.
This should tell us “ADF loaded.” and dump us back at the command prompt.
Enter the command “cd ..” to return to the parent directory. The command “dir” shows us the files in this folder which should include “SMART.EXE”. Enter the command “SMART.EXE”.
At this point the Smart Move software is running. You should see “FOSSIL detected” showing that the serial driver is running and working with Smart Move.
Unfortunately, this is as far as I have got. The software sits at this point with a spinning progress glyph until it times out ages later. I am not yet sure if the issue is because I have the more modern SB-04 (this will surely cause issues as it must speak a different assembly language, and doesn’t have as much RAM as the older 6502 based variants?), or I have more software issues to solve. Hopefully this will be solved if either I get my hands on an SB-01, or someone else tests these instructions for me 🙂
Note the copyright notice names G.W.Babb – a name that is all over the internet, but I haven’t found any recent forum posts by him to ask for help tracking down the software. Gareth – if you’re still about, please get in touch with us as we’re trying to bring the Smart Boxes back to life and would love to know more about loading code into RAM and executing it!
I’ve started putting together a Python library to allow people to use the Economatics Smart Box serial interfaces from a modern computer. Forgive any quality issues, I usually only bodge things together for my own use.
Working with the Economatics Smart Box Serial Interface on a Modern Computer
Well, I had all sorts of fancy plans for how I would reverse engineer the serial protocol to control my ebay purchase “Smart Box” (some of which I will document at some point as they’re useful). Ultimately, I had so much difficulty installing MS .net 1.1 in Wine / PlayOnLinux that I went back to trawling the internet looking for alternative software to wire tap.
Smart Box
I struck gold when I found the following website :
The website includes a download of example code, the core of which is in VB6 and includes many serial commands for controlling the Smart Box (SB-04 version – I understand that older versions work differently, so be warned!), as well as an instruction manual that goes some way to explaining how the box data formats work.
After a bit of messing about in Python, it was fairly trivial to test a number of commands and witness the results. The only major feature I’m not currently sure about is the Analogue Inputs – I don’t know what the pinout is of the 5 pin DIN sockets, and so can’t easily test them. Perhaps a bit of circuit board investigation will help with this.
In summary, I have found the following :
Description
Command
Parameter
Response
Python Example
Set All Motors
10
8 bit value. Note, each pair of bits represents a motor. 01=left, 10=right and 00=stop
n/a
ser.write(chr(10)+chr(0b01010101)) # rotate all motors to the left
Motor <x> Left
12
1 to 4
n/a
ser.write(chr(12)+chr(1)) # rotate motor ‘A’ to the left
Motor <x> Right
13
1 to 4
n/a
ser.write(chr(13)+chr(1)) # rotate motor ‘A’ to the right
Motor <x> Stop
14
1 to 4
n/a
ser.write(chr(14)+chr(1)) # stop motor ‘A’
Set All Digital Outputs
20
8 bit value
n/a
ser.write(chr(20)+chr(0b11111111)) # turn all digital outputs on
Get Analogue <x>
40 (TBC)
1 to 4
8 bit value??
ser.write(chr(40)+chr(1)) # send me analogue input ‘A’
Set Low Resolution Analogue
45 (TBC)
n/a
n/a
ser.write(chr(45)) # set low resolution analogue mode
Get All Digital Inputs
90
n/a
8 bit value. Note the command seems to respond with three bytes, although the first identifies the status of each input.
ser.write(chr(90)) # send me the status of the digital inputs
Get Digital Input <x>
91 (TBC)
1 to 8
0 or 1 (in 8 bit value)
ser.write(chr(45)+chr(1)) # send me the status of digital input 0
The following example switches on motor ‘A’ for 5 seconds, stops it for 0.5 seconds, runs it backwards for 2 seconds and then stops it. Note the serial port will need setting – I have used ‘/dev/ttyUSB0’ as this is the correct port for my USB to RS232 adapter on my Linux machine.
#!/usr/bin/python
# https://elephantandchicken.co.uk/stuffandnonsense
# 04/03/2020
import time
import serial
# This example tests motor output A
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
ser.write(chr(12)+chr(1))
time.sleep(5)
ser.write(chr(14)+chr(1))
time.sleep(0.5)
ser.write(chr(13)+chr(1))
time.sleep(2)
ser.write(chr(14)+chr(1))
ser.close()
The following example reads the status of all digital inputs (aka “Digital Sensors”) 20 times.
#!/usr/bin/python
# https://elephantandchicken.co.uk/stuffandnonsense
# 04/03/2020
import time
import serial
# This example reads in the digital sensors and displays their status
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
# Flash Digital Outputs to show that the program is running
ser.write(chr(20)+chr(255)) # all on
time.sleep(0.1)
ser.write(chr(20)+chr(0)) # all off
time.sleep(0.1)
i = 0
while i < 20:
ser.write(chr(90)+chr(1)) # request digital input status
time.sleep(1) # wait (ages) for the response
readVal = 0 # clear variables
readByte = 0
readByte = ord(ser.read(1)) # read the first waiting byte in the buffer
while ser.inWaiting() > 0: # if there is more data in the buffer
readVal = ord(ser.read(1)) # read it to clear it
print "result : ",format(readByte, '08b') # print the first byte in boolean format
i+=1 # increment counter for the while loop
ser.close()
I still have some more work to do, regarding confirming exactly how these commands work (for example, what are the second and third bytes from the digital read response?). Additionally, I suspect that it is possible to set the voltages, but don’t know how. I’m (absolutely) guessing that command 11 might be motor speed.
Additionally, please contact me if you know any more details of the control scheme, or the analogue port pinout.
The following is my first attempt at controlling the LCD on my Wichit Sirichote (URL updated 2024 to new website) Single Board Computer. Please forgive any terrible programming as I’m not very familiar with assembly language, and even less so with 68k assembly language programming. I’ve tried to make the code a little modular so the subroutines can be re-used. I previously described the software setup I’m using to program the board from Linux here. There are two versions of the same program (almost) in this post, the second of which animates the little stickman using interrupts for timing.
; Hardware Locations in Memory
gpio1 equ $f0000 ; LED PORT
lcdcw equ $60000 ; LCD command WR
lcddw equ $60001 ; LCD data WR
lcdcr equ $60002 ; LCD command RD
lcddr equ $60003 ; LCD data RD
; LCD Commands
lcdbsy equ $80 ; LCD BUSY
lcd8bt equ $38 ; Select 8 bits interface
lcdinc equ $06 ; Entry Mode - Increment
lcddcb equ $0E ; Display On, Cursor On, Blink OFF
lcddnc equ $0C ; Display On, Cursor Off, Blink Off
lcdoff equ $08 ; Display Off, Cursor Off
lcdclr equ $01 ; Clear Display
lcd1st equ $80 ; Set first line start
lcd2nd equ $C0 ; Set second line start
; Program location in memory
org $400 ; start of program
START
move.l #stack,a7 ; sure
move.w #$2100,sr ; what these do
bsr subinit ; initialise LCD
bsr subcust ; send little man
bsr subclr ; clear screen
bsr subrow1 ; go to home address
;send text
lea text1,A2 ; get address of text string
bsr subsend ; send the text located at A2
bsr subrow2 ; go to second line
lea text2,A2 ; next line text address
bsr subsend ; send it
loop jmp loop ; forever
; ---------------------------------------------------
sublcdr ; wait for lcd ready
movem.l D0-D1,-(sp)
move.w #$ffff,D1
lcd_bu0
move.b (lcdcr),D0
andi.b #lcdbsy,D0
beq.s lcd_bu1
dbra D1,lcd_bu0
moveq #1,D1
lcd_bu1
movem.l (sp)+,D0-D1
rts
subinit ; set up the display
move.b #lcd8bt,(lcdcw) ; write command $38 - 8 bit mode
move.b #lcd8bt,(lcdcw)
move.b #lcd8bt,(lcdcw)
bsr sublcdr ; wait for ready
move.b #lcdinc,(lcdcw) ; write command $06 increment cursor
bsr sublcdr
move.b #lcddnc,(lcdcw) ; display on, cursor off, blink off
rts
subclr ; clear the display
bsr sublcdr ; wait for ready
move.b #lcdclr,(lcdcw) ; write command $01, clear display
rts
subrow1 ; go to first line
bsr sublcdr
move.b #lcd1st,(lcdcw) ; write command $80, first line start
rts
subrow2 ; go to second line
bsr sublcdr
move.b #lcd2nd,(lcdcw) ; write command $C0, first line start
rts
subsend ; send string that starts at A2, and ends with zero
movem.l D0,-(sp)
ss1 bsr sublcdr
move.b (A2)+,D0
beq.s senddone
bsr sublcdr
move.b D0,(lcddw)
bra ss1 ; blt next
senddone
movem.l (sp)+,D0
rts
subcust ; create and send a custom character
bsr sublcdr
move.b #$48,(lcdcw) ; custom char 0 edit
lea man,A2 ; send data for man (note, can't have 0 in data)
bsr subsend
rts
; string to display, terminating with zero
text1 dc.b 'This is a M68008',0
text2 dc.b 1,' Doing Stuff! ',1,0 ; 1 gives special char 1. (a little man)
man dc.b %01110,%01110,%00100,%01110,%10101,%00100,%01010,%01010,0
ram ds.b 32 ; not sure
stack equ * ; what these do
This second version uses interrupts for timing a simple animation, but there is more code that I do not understand in it, so please forgive me if there are non-critical errors. The code isn’t very efficient in its use of data registers.
; Hardware Locations in Memory
gpio1 equ $f0000 ; LED PORT
lcdcw equ $60000 ; LCD command WR
lcddw equ $60001 ; LCD data WR
lcdcr equ $60002 ; LCD command RD
lcddr equ $60003 ; LCD data RD
; LCD Commands
lcdbsy equ $80 ; LCD BUSY
lcd8bt equ $38 ; Select 8 bits interface
lcdinc equ $06 ; Entry Mode - Increment
lcddcb equ $0E ; Display On, Cursor On, Blink OFF
lcddnc equ $0C ; Display On, Cursor Off, Blink Off
lcdoff equ $08 ; Display Off, Cursor Off
lcdclr equ $01 ; Clear Display
lcd1st equ $80 ; Set first line start
lcd2nd equ $C0 ; Set second line start
; Program location in memory
org $400 ; start of program
START
move.l #service_level2,$68 ; not
move.l #stack,a7 ; sure
move.w #$2100,sr ; what these do
move.b #$0,d2
move.b #$0,d3
move.b #0,d4
bsr subinit ; initialise LCD
bsr subcust ; set up little man in char 1 & 2
bsr subclr ; clear screen
bsr subrow1 ; go to home address
;send text
lea text1,A2 ; get address of text string
bsr subsend ; send the text located at A2
loop cmpi.b #1,d4 ; Don't re-send if you've already done so
bge loop ; loop if already shown
bsr subrow2 ; pre-move to the start of the second line
cmpi.b #1,d3
blt alt ; go to alt if d3<1
lea text2,A2 ; send text2
bsr subsend ; send it
move.b #1,d4
bra loop
alt lea text3,A2 ; send text3
bsr subsend
move.b #1,d4
bra loop ; forever - note jmp is an absolute address, bra is rel
; ---------------------------------------------------
service_level2
addi.b #1,d2 ; increment d2
cmpi.b #50,d2 ; check if d2 is 50 or more
blt skip ; rte if not 50
clr.b d2 ; reset d2 to 0
move.b d3,gpio1 ; debug code - shows status on leds
clr.b d4 ; reset "don't send again" value
addi.b #1,d3 ; increase d3 (which line 2 to send)
cmpi.b #2,d3 ; check if d3 is too big
blt skip ; if it isn't, finish
clr.b d3 ; if it is, make it = 0
skip rte ; return
sublcdr ; wait for lcd ready
movem.l D0-D1,-(sp)
move.w #$ffff,D1
lcd_bu0
move.b (lcdcr),D0
andi.b #lcdbsy,D0 ; check if the lcd is busy
beq.s lcd_bu1
dbra D1,lcd_bu0
moveq #1,D1
lcd_bu1
movem.l (sp)+,D0-D1
rts
subinit ; set up the display
move.b #lcd8bt,(lcdcw) ; write command $38 - 8 bit mode
move.b #lcd8bt,(lcdcw)
move.b #lcd8bt,(lcdcw)
bsr sublcdr ; wait for ready
move.b #lcdinc,(lcdcw) ; write command $06 increment cursor
bsr sublcdr
move.b #lcddnc,(lcdcw) ; display on, cursor off, blink off
rts
subclr ; clear the display
bsr sublcdr ; wait for ready
move.b #lcdclr,(lcdcw) ; write command $01, clear display
rts
subrow1 ; go to first line
bsr sublcdr
move.b #lcd1st,(lcdcw) ; write command $80, first line start
rts
subrow2 ; go to second line
bsr sublcdr
move.b #lcd2nd,(lcdcw) ; write command $C0, first line start
rts
subsend ; send string that starts at A2, and ends with zero
movem.l D0,-(sp)
ss1 bsr sublcdr
move.b (A2)+,D0
beq.s senddone
bsr sublcdr
move.b D0,(lcddw)
bra ss1 ; blt next
senddone
movem.l (sp)+,D0
rts
subcust ; create and send a custom character
bsr sublcdr
move.b #$48,(lcdcw) ; custom char 0 edit
lea man,A2 ; send data for man (note, can't have 0 in data)
bsr subsend
rts
; --------------------------------------------------------
; string to display, terminating with zero
text1 dc.b 'This is a M68008',0
text2 dc.b 2,' Doing Stuff! ',1,0 ; 1 gives special char 1. (a little man)
text3 dc.b 1,' Doing Stuff! ',2,0 ; 2 gives special char 2. (a little man arms up)
man dc.b %01110,%01110,%00100,%01110,%10101,%00100,%01010,%01010,%01110,%01110,%10101,%01110,%00100,%00100,%01010,%01010,0
ram ds.b 32 ; not sure
stack equ * ; what these do
Having grown up using computers based on Motorola’s 68k family of microprocessors, I have been considering trying to build a simple 68k processor computer of my own. Given how long it took me to get around to build a breadboard Z80 computer, and with a growing sense that I really should learn how to program a GAL or CPLD to reduce the chip count… I decided to buy one of Wichit Sirichote’s single board computers based on the 68008 processor (URL updated 2024 to new website).
68008 Single Board Computer
The Motorola 68008 is a slightly odd chip which has 32 bit internal functionality, coupled to an 8 bit data bus instead of the 16 bit data bus of the regular 68000. It was designed to be a cheaper / simpler alternative to the 68000 processor.
The following page details how I got to the point that I could run my own software written on a Debian-ish Linux machine, on the 68008 board.
Step 1 – Get the Assembler and Compile it
I decided to use the vasm assembler. It runs on multiple platforms and can assemble code for a large number of processors including the Z80, 6502 and 68008, all of which are of interest to me for various computers / projects. I downloaded the latest release source, which at the time of writing is v1.8g (locally hosted here).
I extracted the source code into a folder called vasm (using the GUI archive tool because I’m lazy), before navigating to within the folder in a terminal. To decompress from the command line you should use the command “tar -xvf ./vasm.tar.gz” from within the same directory – note this is “-xvf” not “-xvzf” as the file appears to be only a tar and not zipped, but misnamed. Given that I’m running linux, I figured I could use the default make file and so all I had to do was run the command :
make CPU=m68k SYNTAX=mot
This tells the compiler what our target CPU family is, as well as the assembly language syntax / style we plan to use (in this case Motorola, rather than the GCC syntax which is a little different).
Once the compiler had finished building the project, I was able to copy the new program called “vasmm68k_mot” from the current directory to where I wanted to run it from – note I didn’t bother installing it and am just running it from a folder in my home directory.
Step 2 – Writing a Test Program in Assembly Language
Wichit Sirichote’s webpage includes a download of several example programs, which are also listed in the manual. The following simple program loads the number 12345678 into a register (d0) and then displays part of it on the LEDs (memory mapped at f0000). The fist line identifies where in memory the program should be located. A copy of this program in assembly can be downloaded here. This is a text file and can be opened and edited in any text editor.
I have saved this assembly program as “FirstTest.asm” in the same location that I have placed the vasm application. After a bit of fiddling, I was able to work out the required parameters to assemble my files into a correctly formatted hex file and settled on the format vasmm68k_mot -m68008 -Fsrec -s19 -o <outputfile.hex> <inputfile.asm>. The -Fsrec parameter uses the Motorola S Record output format, with the -s19 parameter using 16bit S Record mode. So, to assemble the FirstTest.asm file into FirstTest.hex, all in the same folder as the vasmm68k_mot application, I use the following command.
This gives the following feedback that doesn’t indicate there were any errors (if you get errors, double check you pointed it to the correct files and didn’t make any typos in your assembly – also, check that tabs are used between columns).
vasm 1.8g (c) in 2002-2019 Volker Barthelmann
vasm M68k/CPU32/ColdFire cpu backend 2.3f (c) 2002-2019 Frank Wille
vasm motorola syntax module 3.13 (c) 2002-2019 Frank Wille
vasm motorola srecord output module 1.0 (c) 2015 Joseph Zatarski
CODE(acrx2): 12 bytes
Opening the resultant FirstTest.hex file in a text editor shows the following, which is the assembled program in Motorola hex.
If you’ve got this far, congratulations, you’ve cross-assembled a 68k program. Now it is time to load your creation into the 68k Computer.
Step 4 – Connecting the SBC to a Computer
Programs can be loaded directly into RAM on the 68008 board over serial. To connect the 68008 board to a modern computer it is most likely that you’ll need a USB to RS232 adapter, but it is worth noting that since both devices being connected are computers (rather than a computer and a peripheral), both ports are likely to be male. As such, we’ll need a “null modem” cable, which is similar to an ethernet crossover cable in that the TX and RX wires are switched so that you’re not connecting TX to TX and RX to RX. I have been using a cable similar to this linked item, as well as a bodge using a USB to UART and a UART to RS232 adapter to get up and running while I waited for a null modem cable in the post. I have had issues with cheap cables failing in the past and so have ordered a 4 port RS232 box with a USB interface as a replacement. The box hasn’t arrived yet.
Cables
Note it is possible to get “gender changer” adapters which do not cross over the TX and RX pins, meaning that while you can physically connect your computer and the 68008 board, they will not communicate.
Gender Changer – Note this didn’t work for me
Once you have all the right cables, with the 68008 board powered down, connect the null modem cable to the 68008 board and the USB RS232 adapter, plug the USB RS232 adapter into your computer and run the following command.
ls /dev/tty*
There will likely be an item listed as ttyUSB0, or similar. If no serial device is clearly obvious, unplug the USB RS232 adapter and run the command again. Compare the two lists and identify what has changed. This is your serial port. Next, make sure that the software “screen” is installed on your Linux machine by running the following command at the command line and following on screen prompts (either telling you it is already installed and is the latest version, or asking if you would like to install it).
sudo apt install screen
Note that some users on Linux do not have permissions to access serial ports. Running the following command (substituting “MY_USER_NAME” for your user name) and restarting your computer should fix this.
sudo usermod -a -G dialout MY_USER_NAME
Next, run the following command at the command line on your Linux computer (substitute ttyUSB0 for the correct serial port name if you found it to be different earlier).
screen /dev/ttyUSB0 2400
This command connects to the USB RS232 adapter at a baud rate of 2400. Now turn on the 68008 board and you should see the text “68008 MICROPROCESSOR KIT (C)2016 rev2.1” or similar. This shows that communications are working. If you don’t see this, check your connections and cables. Make sure you didn’t have any permissions errors. Try running the “screen” command using sudo.
Step 5 – Loading the Program
Assuming you were able to establish the connection between your Linux computer and the 68008 board, press the “LOAD” button on the 68008 board. You should now see the message “Load Motorola s-record” in the window.
Ready to Upload
Copy the entire contents of the FirstTest.hex to the clipboard, and then paste the copied text into the terminal window in which “screen” is running (often right click in the terminal window and select the option “Paste”). If everything works correctly, once the program is loaded, you should see a message saying that there were no errors.
Upload Successful
Step 6 – Stepping Through the Program
To check that the program is now in memory, press the “PC” button (PC stands for Program Counter) on the 68008 board. If the 7 segment display now shows 00400 20, this is a very good sign. The 00400 is the Program Counter address, where the machine will start running a program from. The “20” is the first byte of the program that was loaded over serial. If it says anything other than “20”, then something isn’t right. Press the “+” key repeatedly, and you should see the following sequence 3C, 12, 34, 56, 78. These are the next few bytes of the program. Press “PC” again to return to the start of your program.
Ready
If the “STEP” button is pressed, the 68008 board will execute the first command in the program – in this case, load 12345678 into the register D0. You can check this by pressing the “REG” key, followed by the “0” (zero) key. The 7 segment display should show 12345678. Press “PC” to return to displaying the current location in the program.
View Data Register D0
Press “STEP” again, and part of this number will be shown on the eight LEDs on the right hand side of the 68008 board.
LED Output
Congratulations, you’ve completed loading and stepping through the tiny example program.
Step 7 – Trying Another Program
The following program is based on one of the other provided examples, modified to alternatively flash every second LED, rather than count in binary as the provided example does.
The code uses the 10 ms tick feature on the board (a 100hz pulse) and an interrupt to time the changes. The (inverse of the) initial state of the LEDs is set in the line “move.l #$55,d1”. Changing the number #$55 (remember this is in hex as indicated by the “$” sign) will change the initial state of the LEDs. For example, replacing it with #$00 will cause all eight LEDs to flash together.
The speed at which the LEDs flash can be changed by modifying the line “cmpi.b #20,d0”. #20 is (in decimal, as there is no “$” sign) the maximum number the code will count to before changing the state of the LEDs. In the example above, #20 means that when the value in d0 reaches 20, the LEDs will be inverted and d0 will be reset to 0. Otherwise, d0 will be increased by 1 and the program will wait for the next 10ms tick to trigger an interrupt. “service_level2” is triggered each time one of these 10ms ticks occur, otherwise the processor runs in the infinite loop “here bra here”.