BBC Micro Development Environment
By modern standards, the BBC Micro is not that much fun to work on. The 2MHz CPU doesn't assemble code particularly quickly, the 32K RAM is quickly exhausted, and the disk drives are rather slow. And even once upgraded to fix all of that, the editing environment is still a bit painful.
For this reason, I prefer to do any BBC development on the PC…
Tools
dasm
The assembler I use is DASM. This is just a random one that I found that wasn't awful, wasn't at version 0.something, and had its own macros. So far it has proven acceptable.
emacs
For editing, I use emacs with my 6502-mode, a slightly modified version of Per Olofsson's dasm-mode.
65Link
John Kortink's 65Link lets you use your other computer for something
useful: a file server for your BBC Micro. It's like having an endless
number of 8-sided discs, but PAGE
stays at &E00.
Compiling
I compile projects using GNU make. emacs supports this fairly well, and it's easy to set up.
It's mainly easy because my Makefiles are so decidedly unclever. Here's pretty much what I use:
.PHONY:all all: ../dasm/bin/dos/dasm.exe mandel.s65 -f3 -lmandel.lst -smandel.sym -omandel.bbc
This assembles mandel.s65
and puts the result in mandel.bbc
.
Getting it onto the BBC with 65Link
My BBC is linked up to my second PC using a 65Link cable. By sharing the relevant 65Link volumes folder, my development PC can copy files to somewhere the BBC can see them immediately.
.PHONY:all all: ../dasm/bin/dos/dasm.exe mandel.s65 -f3 -lmandel.lst -smandel.sym -o_doMANDEL cp _doMANDEL //p1/beebvols/dev/0/
(p1
is the name of my second PC; I've got the 65Link volumes folder
shared out as beebvols
, and dev
is just a random volume.)
Now the file, when assembled, appears on the BBC (when I have the
dev
volume mounted) as $.MANDEL
, albeit with bogus load and
execution addresses.
Setting load and execution addresses with 65Link
65Link stores the addresses in a .lea
file, named after the main
file. The format is a very simple 12 bytes: load address (4 bytes),
exec address (4 bytes) then attributes (4 bytes).
This data can be specified as part of the source code. Put the
following in the source code somewhere, after the first org
in the
code segment, so that the data will appear at the beginning of the
file:
org .-12 ; 12-byte LEA header file for 65link lea_header subroutine dc.l .+12 ;load address dc.l gui ;exec address dc.l 0 ;attributes
In the Makefile, use dd
to split the output file into two, and copy
these two new files to the 65Link volume:
.PHONY:all all: ../dasm/bin/dos/dasm.exe mandel.s65 -f3 -lmandel.lst -smandel.sym -omandel.bbc dd if=mandel.bbc of=_doMANDEL.lea count=12 bs=1 status=noxfer dd if=mandel.bbc of=_doMANDEL skip=12 bs=1 status=noxfer cp _doMANDEL.lea //p1/beebvols/dev/0/ cp _doMANDEL //p1/beebvols/dev/0/
Now the file will have the correct load and execution addresses set automatically based on the source code.
Quick turnaround
Create a !BOOT
file that runs your program with *RUN
(or
whatever). Now you can start it up with Shift+BREAK. Put this bit of
code at the start of your program:
lda #$ff ldy #%11110111 ;clear bit 3 ldx #%00000000 ;don't change any bits jsr osbyte
Now a simple tap of BREAK will re-run your program. Doesn't get much easier than that.
The final version should probably not include this code…
Quick turnaround (Tube)
If you're working on the 6502 second processor, using *RUN
from
!BOOT
to start your program causes it to be run automatically on
each press of BREAK. No auto boot, no BASIC prompt. The above code
doesn't do anything useful, and it's kind of annoying to reload your
program if it's not on drive 0.
This is a standard second processor feature, so you're stuck with it. Fortunately it can be worked around with a BASIC program along the following lines:
10F$="PROGRAM" 20DIMX%&200:$(X%+256)=F$:X%?0=(X%+256)MOD256:X%?1=(X%+256)DIV256:Y%=X%DIV256:A%=5:CALL&FFDD:OSCLI"L."+F$:CALLX%!6
(Set F$
to the name of the program you're going to run.)
This does the equivalent of a *RUN
, but because the actual CALL
is
done from BASIC the system is fooled into thinking BASIC is the active
program. Result: you're back in BASIC on a tap of BREAK, and the whole
thing behaves mostly like it does on an unexpanded system.
Note that this program is almost 128 bytes. It also allocates a
string, and it allocates a 512 byte buffer. You may have to play with
PAGE
, if your program loads low enough – or rewrite my code to be
less wasteful.
(This code will work fine on an unexpanded BBC as well, but the
comment about PAGE
goes double. Maybe even treble…)