[050d522] | 1 | Buchla 700 Firmware
|
---|
| 2 | -------------------
|
---|
| 3 |
|
---|
| 4 | This repository, buchla-68k.git, contains a port of the Buchla 700
|
---|
| 5 | firmware source code to a modern GCC-based cross-compilation
|
---|
| 6 | environment.
|
---|
| 7 |
|
---|
| 8 | The resulting executable code needs to be run on emulated Buchla 700
|
---|
| 9 | hardware, such as the one in the companion repository, buchla-emu.git.
|
---|
| 10 |
|
---|
| 11 | The source code was originally released on Aaron Lanterman's Buchla
|
---|
| 12 | 700 Preservation Page:
|
---|
| 13 |
|
---|
| 14 | http://lanterman.ece.gatech.edu/buchla700/
|
---|
| 15 |
|
---|
| 16 | Aaron seems to have received the source code directly from Lynx Crowe,
|
---|
| 17 | the developer.
|
---|
| 18 |
|
---|
| 19 | The licensing conditions are a little vague; Lynx released the source
|
---|
| 20 | code "for noncommercial personal and educational use" and "as-is with
|
---|
| 21 | no guarantees of completeness or correctness."
|
---|
| 22 |
|
---|
| 23 | While our modifications are in the public domain, Lynx's request still
|
---|
| 24 | applies to the underlying original code. Please respect that.
|
---|
| 25 |
|
---|
| 26 | Note that this is just the code that runs on the Buchla 700's Motorola
|
---|
| 27 | 68k CPU:
|
---|
| 28 |
|
---|
| 29 | 1. The BIOS and ROMP debug monitor.
|
---|
| 30 |
|
---|
| 31 | 2. The MIDAS VII GUI-driven editing and control software.
|
---|
| 32 |
|
---|
| 33 | In particular, there's no code for anything related to the actual
|
---|
[87361de] | 34 | sound generation.
|
---|
[050d522] | 35 |
|
---|
[7913d06] | 36 |
|
---|
[050d522] | 37 | Building with a GCC cross-compiler
|
---|
| 38 | ----------------------------------
|
---|
| 39 |
|
---|
| 40 | *** Setting up the cross-toolchain
|
---|
| 41 |
|
---|
| 42 | To build the code, you need a cross-toolchain, i.e., GCC and binutils,
|
---|
| 43 | for the m68k-none-elf target. Let us show you, how we built the one
|
---|
| 44 | that we use, binutils 2.28 and GCC 6.3.0. It lives in /opt/cross-m68k.
|
---|
| 45 |
|
---|
| 46 | First, binutils:
|
---|
| 47 |
|
---|
| 48 | tar jxvf binutils-2.28.tar.bz2
|
---|
| 49 | cd binutils-2.28
|
---|
| 50 |
|
---|
| 51 | mkdir build
|
---|
| 52 | cd build
|
---|
| 53 |
|
---|
| 54 | ../configure --prefix=/opt/cross-m68k --target=m68k-none-elf
|
---|
| 55 |
|
---|
| 56 | make -j2
|
---|
| 57 | make install
|
---|
| 58 |
|
---|
| 59 | Second, GCC:
|
---|
| 60 |
|
---|
| 61 | # Important! Otherwise, the GCC build won't find the binutils that
|
---|
| 62 | # we just made!
|
---|
| 63 |
|
---|
| 64 | export PATH="/opt/cross-m68k/bin:${PATH}"
|
---|
| 65 |
|
---|
| 66 | tar jxvf gcc-6.3.0.tar.bz2
|
---|
| 67 | cd gcc-6.3.0
|
---|
| 68 |
|
---|
| 69 | mkdir build
|
---|
| 70 | cd build
|
---|
| 71 |
|
---|
| 72 | ../configure --prefix=/opt/cross-m68k --target=m68k-none-elf \
|
---|
| 73 | --enable-languages=c --without-headers
|
---|
| 74 |
|
---|
| 75 | # Don't build everything, because features like GCC's stack
|
---|
| 76 | # protector will otherwise cause trouble.
|
---|
| 77 |
|
---|
| 78 | make -j2 all-gcc all-target-libgcc
|
---|
| 79 | make install-gcc install-target-libgcc
|
---|
| 80 |
|
---|
| 81 | Now, as we put /opt/cross-m68k/bin in our PATH, we should be able to
|
---|
| 82 | run the cross-compiler as follows:
|
---|
| 83 |
|
---|
| 84 | user@host:~$ m68k-none-elf-gcc --version
|
---|
| 85 | m68k-none-elf-gcc (GCC) 6.3.0
|
---|
| 86 | Copyright (C) 2016 Free Software Foundation, Inc.
|
---|
| 87 | This is free software; see the source for copying conditions. There is NO
|
---|
| 88 | warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
---|
| 89 |
|
---|
| 90 | user@host:~$
|
---|
| 91 |
|
---|
| 92 | *** Cross-compiling the source code
|
---|
| 93 |
|
---|
| 94 | Once you have the cross-toolchain in place, invoke
|
---|
| 95 |
|
---|
[cd1d0db] | 96 | make bios.abs
|
---|
[050d522] | 97 |
|
---|
| 98 | from the top-level directory of this repository to build the BIOS and
|
---|
| 99 | ROMP debug monitor.
|
---|
| 100 |
|
---|
| 101 | To build MIDAS VII, invoke
|
---|
| 102 |
|
---|
| 103 | make midas.abs
|
---|
| 104 |
|
---|
| 105 | instead.
|
---|
| 106 |
|
---|
[7913d06] | 107 |
|
---|
[050d522] | 108 | Building with Alcyon C
|
---|
| 109 | ----------------------
|
---|
| 110 |
|
---|
| 111 | Lynx developed the Buchla 700 firmware on an 68k-based Atari system
|
---|
| 112 | with the Alcyon C compiler, assembler, and linker from Atari's TOS
|
---|
| 113 | Developer Kit.
|
---|
| 114 |
|
---|
| 115 | If you want to relive this experience, you can do so thanks to the
|
---|
| 116 | Hatari emulator, which emulates a suitable Atari system. Here's the
|
---|
| 117 | idea:
|
---|
| 118 |
|
---|
| 119 | * The hatari/c subdirectory contains the Atari C compiler,
|
---|
[7913d06] | 120 | assembler, and linker. It is turned into a hard drive image for
|
---|
| 121 | the emulator's C: drive.
|
---|
[050d522] | 122 |
|
---|
| 123 | * The hatari/d subdirectory is shared with the emulator, i.e., it is
|
---|
[7913d06] | 124 | not turned into a hard drive image. It is the emulator's D: drive.
|
---|
[050d522] | 125 |
|
---|
| 126 | Any changes to this directory from inside the emulator are
|
---|
| 127 | instantaneously visible outside the emulator, and vice versa. We
|
---|
| 128 | use this as a means of communication between these two worlds.
|
---|
| 129 |
|
---|
| 130 | The subdirectories under hatari/d contain links to the original
|
---|
| 131 | source code files. In addition, the compiled results go to
|
---|
| 132 | hatari/d/out.
|
---|
| 133 |
|
---|
| 134 | * We have a Python script (hatari/rem.py) that acts as a remote
|
---|
| 135 | control for the emulator. It issues the commands required to
|
---|
| 136 | compile or assemble the source code files.
|
---|
| 137 |
|
---|
| 138 | You PATH needs to be set, such that the shell can find the Hatari
|
---|
| 139 | executable:
|
---|
| 140 |
|
---|
| 141 | user@host:~$ hatari --version
|
---|
| 142 |
|
---|
| 143 | Hatari v2.0.0 - the Atari ST, STE, TT and Falcon emulator.
|
---|
| 144 |
|
---|
| 145 | Hatari is free software licensed under the GNU General Public License.
|
---|
| 146 |
|
---|
| 147 | user@host:~$
|
---|
| 148 |
|
---|
| 149 | We use Hatari 2.0.0 with version 0.9.8 of the open-source TOS
|
---|
| 150 | replacement EmuTOS.
|
---|
| 151 |
|
---|
| 152 | Now you need to run two things in parallel, the remote control Python
|
---|
| 153 | script as well as the Hatari emulator. The Python script goes
|
---|
| 154 | first. In one shell window, invoke
|
---|
| 155 |
|
---|
| 156 | make rem
|
---|
| 157 |
|
---|
| 158 | from the top-level directory of the repository to start the
|
---|
| 159 | script. The script then waits for the emulator to come up and connect
|
---|
| 160 | to it. Now run Hatari. In another shell window, invoke
|
---|
| 161 |
|
---|
| 162 | make emu
|
---|
| 163 |
|
---|
[7913d06] | 164 | from the top-level directory of the repository. This creates a hard
|
---|
| 165 | drive image from hatari/c and starts the emulator with appropriate
|
---|
[cbe2c15] | 166 | command line options.
|
---|
[050d522] | 167 |
|
---|
| 168 | When the EmuTOS desktop comes up, open the C:\BIN folder and run
|
---|
| 169 | SH.TTP without any parameters. This opens a Unix-like shell, the Okami
|
---|
| 170 | Shell. This is the shell that the Python script expects to control.
|
---|
| 171 |
|
---|
| 172 | Now, back in the window with the Python script, press the enter
|
---|
| 173 | key. This tells the Python script to start sending commands to the
|
---|
| 174 | shell in the emulator.
|
---|
| 175 |
|
---|
| 176 | Compiling the C and assembly language files of the source code takes
|
---|
| 177 | quite a while. Once the process is complete, the hatari/d/out
|
---|
| 178 | directory contains the following files:
|
---|
| 179 |
|
---|
| 180 | * C source code (.c) files get compiled into assembly language
|
---|
| 181 | source code (.s) files, and then assembled into object (.o) files.
|
---|
| 182 |
|
---|
| 183 | We keep both, .s and .o files. This proved useful when porting the
|
---|
| 184 | original source code to the cross-toolchain, because we could
|
---|
| 185 | compare the compiler output of the cross-toolchain to the original
|
---|
| 186 | output of the Alcyon C toolchain.
|
---|
| 187 |
|
---|
| 188 | This made us realize, for example, that Alcyon C uses 16-bit int
|
---|
| 189 | values, whereas GCC defaults to 32-bit int values.
|
---|
| 190 |
|
---|
| 191 | * Assembly language source code (.s) files get assembled into object
|
---|
| 192 | (.o) files. We keep those, too.
|
---|
| 193 |
|
---|
| 194 | * Some of the object files (.o) get archived into static library
|
---|
| 195 | (.a) files.
|
---|
| 196 |
|
---|
[cbe2c15] | 197 | * bios.abs, which is the BIOS and ROMP debug monitor.
|
---|
[050d522] | 198 |
|
---|
| 199 | * midas.abs is notably absent. Its object (.o) files are all there,
|
---|
| 200 | but our Atari TOS Developer Kit is newer than Lynx's and it comes
|
---|
| 201 | with a different linker (aln), which is not entirely compatible
|
---|
| 202 | with the older linker that Lynx used (link68).
|
---|
| 203 |
|
---|
| 204 | While it would be possible to get linking to work with aln, we
|
---|
| 205 | decided to focus our attention on the cross-toolchain instead.
|
---|
| 206 |
|
---|
[cbe2c15] | 207 | For your convenience, all the .s, .o, and .a files, as well as
|
---|
| 208 | bios.abs can also be found in the alcyon subdirectory of this
|
---|
| 209 | repository. Just in case you are interested in them, but would prefer
|
---|
| 210 | not to go through the emulator exercise.
|
---|
[d44e001] | 211 |
|
---|
| 212 |
|
---|
| 213 | Pitfalls
|
---|
| 214 | --------
|
---|
| 215 |
|
---|
| 216 | There are a few differences between the Alcyon compiler and a
|
---|
| 217 | modern-day GCC cross-compiler for the Motorola 68k.
|
---|
| 218 |
|
---|
| 219 | * Alcyon uses 16-bit integers, whereas GCC defaults to 32-bit
|
---|
| 220 | integers. That's why we pass the -mshort option to GCC.
|
---|
| 221 |
|
---|
| 222 | * The Alcyon compiler's ABI assumes that registers A2 and D2 are
|
---|
| 223 | saved by the caller of a function, if needed. GCC, however,
|
---|
| 224 | assumes that it's the called function that is responsible for
|
---|
| 225 | preserving A2 and D2.
|
---|
| 226 |
|
---|
| 227 | Right now, we work around this issue by passing the -ffixed-d2 and
|
---|
| 228 | -ffixed-a2 options to GCC. This prevents GCC from using these two
|
---|
| 229 | registers at all when generating code.
|
---|
| 230 |
|
---|
| 231 | Ultimately, we should fix the hand-written assembly language
|
---|
| 232 | functions to preserve A2 and D2, so that GCC code generation can
|
---|
| 233 | use all registers.
|
---|