First time with BBC Basic

      No Comments on First time with BBC Basic

So what was your first program? You know, the first one that meant anything.

My guess is that when you unwrapped your first home computer (mine was a Sinclair Spectrum 48K) the lines of code you typed were little more than snippets – changing some colours on the display, perhaps, or making rude words scroll endlessly down the screen. You may even have progressed to something like:

 INPUT "What is your name?", N$
PRINT "Hello ",N$

Thrilling stuff.

Then you started looking around for something a little more meaningful. I’m a photographer, in addition to my other sins, and at the time I got my Spectrum I was a section editor on a weekly publication called The Photo. It was a partwork (a magazine that builds into an encyclopaedia) and I was responsible for running the technical sections. So naturally I searched for something photographic that needed computing.

And depth of field turned out to be the ideal candidate. If you’re not into photography, depth of field defines how much of the scene in front on the camera is in focus, in terms of distance from the lens. The point where you’ve focused the lens is obviously sharp, but a region either side will look in-focus too. This has to do with ‘circles of confusion’ (one of my favourite photographic terms). In brief, a point of light that isn’t in focus will form a circle (well, actually a disc, but let’s not quibble) instead of a sharp point. You can clearly see this in areas of the image that are way out of focus – it’s what gives rise to that effect often referred to by that godawful word ‘bokeh’.

However, if the disc is sufficiently small, your eye won’t be able to tell it apart from a point that is fully in focus. How small is small? That depends. In the days of plate or medium-format cameras the maximum size was considered to be 0.05mm (that’s the size of the circle of confusion in the image being formed on the film). For 35mm systems, this was commonly reduced to 0.033mm or 0.03mm. And pernickety people might insist on reducing this to 0.025mm.

The other factors that affect depth of field are the focal length of the lens, the aperture (f-stop) selected and the distance from the lens to the main point of focus. The shorter the focal length or smaller the aperture, the more depth of field. That’s why, on smartphones, pretty much everything in the image is in focus, because they have incredibly short focal length lenses.

There’s another handy phenomenon connected to all this – hyperfocal distance. In most of the technical literature this is defined as being the closest distance from the lens that is rendered acceptably sharp (ie, it’s the closest limit of depth of field) when the lens is focused at infinity.

In practical terms, most photographers understand it slightly differently. It’s the closest distance at which you can focus the lens so that everything from there to infinity is kept sharp by depth of field. In fact, everything from half that distance to infinity will be sharp. This is a handy thing to know because in fast-moving situations, such as a news or documentary photographer might encounter, you can set the focus ring to the hyperfocal distance for the aperture you’re using and shoot away, letting depth of field take care of keeping things in focus. (This was, of course, in the days of manual-focus lenses.)

In case you’re wondering, the difference between a hyperfocal distance calculated using the text book definition and one based on the practical application is very small.

You don’t need to calculate this: lenses always used to have focus scales with depth of field markings for various apertures. You could just set the infinity symbol against one of these marks and that was the hyperfocal distance set.

But, dammit, I was looking for something to compute.

Luckily, I had a copy of ‘The Photographic Lens’ by Sidney Ray. In fact, Sidney was one of our key contributors on The Photo, a charming man who I relied on for technical insights. And the book contains the necessary formulae for calculating depth of field and hyperfocal distance. I still have that book.

And so that was my first real program. I hacked it together on the Speccy and even used the results to publish some tables in The Photo.

Then, when I graduated from the Spectrum to a BBC Micro Model B, the first thing I did (aside from displaying rude words) was re-create this program.

My original copies are long gone, of course. But I was playing around with the BeebEm emulator, running on a Windows VM on my iMac (is that enough layers of abstraction for you?) and thought, why not rewrite that program?

Why not indeed.

I was a little easier this time around. I was using an emulated BBC Master with the Basic Editor ROM installed. It’s not exactly Sublime Text but *BE was a revelation when it first came out.

The program being edited in Acornsoft’s Basic Editor. Basic, isn’t it?

I decided to write as much of the program as I could from memory – not of the original program but of BBC Basic. It was surprising how much came back, but I confess I had to resort to the manual fairly quickly. It reminded me, though, how good BBC Basic was (and still is), not least in its structured nature. I mean, named procedures and functions with parameters on an 8-bit home micro from the early 1980s? It’s impressive.

The program below is nothing like my original. I have a vague memory that, back then, the program printed out a table with one axis being focus distances (like this new program) and the other axis being apertures. Each cell contained the minimum/maximum limits of depth of field. Also, I think the original asked you to enter details (focal length, depth of field and circle of confusion), then printed the table. There was a cursor line to make it easier to read across the table – I was very proud of how you could move this line up and down with the cursor keys – but it was actually somewhat pointless. But if you wanted to change, say, the focal length you had to end the program and start again.

This time around, there’s a main program loop and a menu allowing you to change any of the four main parameters, which include a focus distance.

‘Enter circle of confusion’ sounds like a command from Dungeons & Dragons (I imagine). Who could resist such an invitation?

The program then displays the depth of field for that combination of factors, the hyperfocal distance for that lens/aperture combination and a table of depths of field for various focus distances. The figures look sensible, so I think it’s working okay. And it was fun. Here’s the code, for what it’s worth:

REM >DOF
REM Depth of Field Calculator
MODE 3

REM --- MAIN GLOBALS ---
flen% = 50   : REM focal length, mm
fstop = 8.0  : REM aperture
circ = 0.033 : REM circle of confusion, mm
dist = 5.0   : REM focus point in meters
DoFnear = 0.0
DoFfar = 0.0
hyperfocal = 0.0

REM --- Set up distance index for table ---
distances% = 17 : REM max index for dists array
DIM dists(distances%)
FOR I% = 0 TO distances%
  READ dists(I%)
NEXT

REM --- Main Loop ---
done% = FALSE
REPEAT
  CLS
  PROCdisplay
  sel$ = CHR$(FNmenu)
  IF sel$ = "Q" THEN done% = TRUE
  IF sel$ = "A" THEN fstop = FNsetparam(sel$)
  IF sel$ = "C" THEN circ = FNsetparam(sel$)
  IF sel$ = "D" THEN dist = FNsetparam(sel$)
  IF sel$ = "F" THEN flen% = FNsetparam(sel$)
UNTIL done% = TRUE
CLS
END

REM distances for table
DATA 0.5,0.7,1,1.5,2,3,4,6,8,12,15,25,30,50,75,100,150,200

DEF FNsetparam(ch$)
CLS
IF ch$="A" THEN prompt$="aperture":min = 1:max = 130:default=fstop
IF ch$="F" THEN prompt$="focal length":min=8:max=1000:default=flen%
IF ch$="C" THEN prompt$="circle of confusion":min=0.025:max=0.05:default=circ
IF ch$="D" THEN prompt$="subject distance":min=0.1:max=1000:default=dist
prompt$ = "Enter " + prompt$
PRINT TAB(5,6);prompt$
INPUT TAB(LEN(prompt$) + 6,6);">"param
result = param
IF param < min THEN result = min
IF param > max THEN result = max
IF param = 0 THEN result = default
=result

DEF PROCdisplay
PROCcalc(dist)
PROChyper
@% = &01000006
PRINT TAB(1,0);"Focal Length: "; flen%; "mm"
@% = &01000004
PRINT TAB(23,0);"Aperture: f/"; fstop
@% = &01020105
PRINT TAB(41,0);"Subj Dist: "; dist;  "m"
@% = &01020305
PRINT TAB(67,0);"CoC: "; circ; "mm"
@% = &01020106
PRINT TAB(1,1); "DoF Near: " ; DoFnear ; "m"
PRINT TAB(23,1); "DoF Far: " ; FNfarstr(DoFfar)
PRINT TAB(41,1); "Hyperfocal distance: "; hyperfocal; "m"
PRINT TAB(13,2); "dist"; TAB(26,2); "near"; TAB(41,2); "far"
PRINT TAB(13,3); "----"; TAB(26,3); "----"; TAB(40,3); "----"
FOR I% = 0 TO distances%
  PROCcalc(dists(I%))
  @% = &0100003
  PRINT TAB(13,4+I%), dists(I%); "m"
  @% = &01020106
  PRINT TAB(23,4+I%)DoFnear;"m"
  fardist$ = FNfarstr(DoFfar)
  PRINT TAB(38,4+I%); SPC(6-LEN(fardist$)); fardist$
NEXT
ENDPROC

DEF FNfarstr(far)
IF far > 0 THEN far$ = STR$(far)+"m" ELSE far$ = "-inf-"
=far$

DEF PROCcalc(dst)
fdist = dst * 1000  : REM work in mm
fact = fdist * circ * fstop
DoFnear = fdist / (1 + (fact / flen% ^ 2))
DoFnear = DoFnear / 1000
DoFfar = fdist / (1 - (fact / flen% ^ 2))
DoFfar = DoFfar / 1000
ENDPROC

DEF PROChyper
hyperfocal = ((flen% ^ 2 / (circ * fstop)) + flen%) / 1000
ENDPROC

DEF FNmenu
PRINT TAB(1,23);"(F)ocal length : (A)perture : (D)istance : (C)ircle of Confusion : (Q)uit"
opt% = FALSE
REPEAT
  key% = INKEY(0)
  REM convert to uppercase if necessary
  key% = key% AND &DF
  IF key%=65 OR key%=67 OR key%=68 OR key%=70 OR key%=81 THEN opt%=TRUE
UNTIL opt% = TRUE
=key%

[UPDATE 11/09/2018] I used Mode 3 in the program above because … well, I had a vague memory of always using that mode. (Or Mode 131 on the Master.) I never much liked squeezing the output from programs into a 40 character-wide screen, and never used the Beeb’s 20-character modes. I didn’t program (or play) games and had a limited need for colour.

But I was surprised when recreating my program how few lines of text were available. And that’s because I’d got a bit confused.

Mode 3 on the Beeb was really intended for communications. It’s a non-graphic mode that gives the 80 x 25 character display needed to match various terminal standards. But I think I mostly used it because it’s just slightly less memory-hungry than the other 80-column mode, Mode 0. In Mode 0 (and also Modes 1 and 2) you lost 20K of the Beeb’s alleged 32K to display memory, so nominally just under 12K left over for your program (and actually somewhat less because of OS requirements, so more like 9K). In Mode 3, you clawed back another 4K for program space.

Even when I upgraded to the BBC Master 128, with its shadow memory making such considerations obsolete, I tended to carry on with that mode (now Mode 131) just out of habit.

But my depth of field program doesn’t require even as much as 12K. Switching to the 80×32 character display of Mode 0 gives me a bit more room to play with.

And yeah, you can cram that information into a 40-column display, but it ain’t pretty.

[UPDATE 12/09/2018] The programs (80- and 40-column versions) are now running on an actual Beeb. I transferred them to my recently fixed BBC Master 128. And this was much easier than it had any right to be thanks to my recent acquisition of a RetroClinic DataCentre. But I think I’ll make that the subject of another post.

 

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.