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
|
---|
34 | sound generation.
|
---|
35 |
|
---|
36 |
|
---|
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 |
|
---|
96 | make bios.abs
|
---|
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 |
|
---|
107 |
|
---|
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,
|
---|
120 | assembler, and linker. It is turned into a hard drive image for
|
---|
121 | the emulator's C: drive.
|
---|
122 |
|
---|
123 | * The hatari/d subdirectory is shared with the emulator, i.e., it is
|
---|
124 | not turned into a hard drive image. It is the emulator's D: drive.
|
---|
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 |
|
---|
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
|
---|
166 | command line options.
|
---|
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 |
|
---|
197 | * bios.abs, which is the BIOS and ROMP debug monitor.
|
---|
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 |
|
---|
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.
|
---|
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.
|
---|