BBC Micro on FPGA

Introduction

Chuckie Egg running on BBC FPGA

Chuckie Egg running on BBC FPGA

Following on from the Sinclair Spectrum, the other machine I got to play with a lot as a kid was the Acorn BBC Micro.  In mid-to-late 80s UK there were several of these in every primary school (unless mine was unusually affluent). Secondary schools had them by the roomful at least until the mid-nineties, when they were finally supplanted by the might of the PC.

For many of my generation this was probably their first experience of computing without the agonising wait for programs to load from tape; the Beeb of course supported a tape interface, but most were installed with a 5 1/4” (very) floppy disk drive. Graphically, the ubiquitous Microvitec Cub monitor was a big step up from the usual re-purposed TV.

There were several versions of the BBC, each in a similarly styled beige box with integral keyboard. The originals, Models A and B, were pretty similar with the A having half as much memory. The Model A could be upgraded later to match the Model B specification, but the B proved more popular anyway. Later came the memory-enhanced Model B+, with subsequent revisions becoming the Master series. The most obvious additions in the Masters were the cartridge slots and numeric keypad, as well as even more RAM.

With fond memories of educational titles like “Granny’s Garden”, and less educational ones like “Pole Position” and “Boffin”, the BBC B seemed like a worthy machine to bring back to life inside an FPGA.

Architecture

The heart of the BBC was the popular 6502 processor, variants of which were also found in machines by Atari, Commodore and Apple, among many others. A summary of the architecture for the model B is as follows, along with the current status of each item in the FPGA design:

  • DONE – CPU: MOS 6502 running at 2 MHz, except when accessing certain peripherals when the clock would be automatically reduced to 1 MHz.
  • DONE – RAM: 32KB DRAM running at 4 MHz, time-sliced with and refreshed by the video hardware (no contention!).
  • DONE – ROM: 16KB MOS ROM, 4x 16KB paged ROM slots. One of the paged ROM slots is taken up by the BASIC interpreter, with another usually filled with the Disk Filing System (DFS). Third party expansions allow more than 4 ROMs to be fitted.
  • DONE – Bitmapped display: Motorola MC6845 CRT Controller + custom Ferranti Video ULA (VIDPROC). The 6845 provides addresses to the DRAM, and additional address-wrap logic means that hardware scrolling can be achieved without the display running beyond the end of the video RAM.
  • MOSTLY – Teletext mode (MODE 7): Mullard SAA5050 character generator.
  • DONE – Sound: Texas Instruments SN76489 accessed via the System VIA.
  • DONE – IO: Two 6522 VIA chips provide a pair of 8-bit GPIO ports each, timers and interrupt inputs. The System VIA provides indirect access to the keyboard and various other hardware over a “slow bus”. One of its timers is used for a 10 ms OS tick, and the four external interrupts are used by the keyboard, vertical sync, ADC and light pen interface. The user VIA drives the printer and user ports, the latter directly.
  • NOT IMPLEMENTED – Serial: 6850 UART and another Ferranti ULA (SERPROC) provide an RS-423 serial port and a “Kansas City” tape interface.
  • NOT IMPLEMENTED – Disk Interface: In the earlier machines an Intel 8271 floppy disk controller provides an interface for a pair of double-sided drives.
  • NOT IMPLEMENTED – Network: Acorn’s own “Econet” is catered for by a Motorola 68B54 Advanced Data Link Controller IC. Like the disk interface this was an optional extra and also requires the addition of the NFS ROM.
  • NOT IMPLEMENTED – ADC: Four multiplexed analogue inputs, useful for joysticks and instrumentation, are provided by a uPD7002 12-bit ADC.
  • Buses: Two expansion buses are exposed on the underside of the machine. The 1 MHz bus was used by peripherals such as the teletext interface, whilst the Tube port is a co-processor bridge. No attempt has been made to make these buses available to the outside world. However, simulating them on the expansion headers should take very little effort.

FPGA Implementation

BBC FPGA on Terasic DE1

BBC FPGA on Terasic DE1

The project was, like the Spectrum, implemented on a Terasic DE1 board with an Altera Cyclone II FPGA. The entire design is written in VHDL, and it fits in 2907 logic elements when compiled on Quartus 9.1. This is about 16% of the capacity of the EP2C20. A small amount of on-chip memory is used for the teletext character generator ROM, with the program ROMs residing in off-chip flash.

At this stage no attempt has been made to add a scan-doubler for the video output, so a PAL TV is required for display. A SCART lead can be made to connect to the VGA port on the DE1; the HSYNC pin generates PAL compatible CSYNC, and the VSYNC pin is driven to +5 V. The latter should be connected to pin 16 of the SCART plug to make the TV go into RGB mode.

Sound is available on the green line-out connector and this can be fed into the SCART lead as well if desired, or to separate speakers.

A PC PS/2 keyboard is required (here is the keymap, click for larger).

Key map for FPGA BBC using a PC keyboard

Key map for FPGA BBC using a PC keyboard

Download the .sof file to run on your own DE1. For normal operation switches 8 and 9 should be in the up position, the rest down. Switch 9 is system reset, switch 8 is the run/stop input to the hardware debugger (more on this later). The remaining switches appear as the keyboard DIP switches, most of which are unused, but the lower three control the startup MODE.

ROMs

I am not providing the ROM images for download here as I am not sure of their legal status and they are not hard to find elsewhere anyway. The following ROMs are required:

  • os12.rom
  • basic2.rom
  • supermmc.rom

The MMC ROM is part of MMBEEB and provides access to disk images on an SD card.

The three ROM images must be concatenated and loaded into the bottom of the DE1’s flash using the tool that came with the board. I joined the ROMs on Linux just by doing:

$ cat os12.rom basic2.rom supermmc.rom >all.rom

 

Note that the ROM order is important, and at the very least the MOS ROM must come first.

UPDATED:  The latest version of this project now includes some addressing changes to allow the BBC ROM images to coexist with those from the Spectrum.  8x 16 KB banks are reserved in the DE1’s Flash address space for use by the BBC, and the relevant ROM images must be loaded first using the tools that came with the DE1 board.

  • 0x20000 – Sideways ROM
  • 0x24000 – Sideways ROM
  • 0x28000 – Sideways ROM (load with SUPERMMC)
  • 0x2C000 – Sideways ROM (load with BASIC)
  • 0x30000 – Not used
  • 0x34000 – Not used
  • 0x38000 – Not used
  • 0x3C000 – MOS

Known Issues

The MODE 7 teletext support does not implement the “hold graphics” feature, which may corrupt some displays. Character rounding is not implemented either, which doesn’t matter so much.

Occasionally the machine will hang, usually at the same point in certain programs. I haven’t spent much time tracking this one down but it appears to be something to do with interrupt handling, so it could be a CPU bug. Manic Miner, for example, starts with an animated graphic like on the Spectrum. On the BBC this uses a vertical sync event handler and so runs in interrupt context. On the FPGA the animation and scrolling ticker run too fast and at irregular pace, and the game can’t be started.

Some of the unimplemented features would be nice to have. In particular the serial hardware for the tape interface, and the floppy disk controller to enable a real drive to be attached. I plan to add these in due course.

Credits

The following blocks are used in the design. Modifications were required in some cases – details on the design page.

Downloads

Update 2016-01-13: The files are now also available on GitHub


50 thoughts on “BBC Micro on FPGA

  1. Jeff Braine

    Again, thanks for making the source for this available Mike. I think I’ll be taking a look at this once I’ve finished the spectrum project 🙂

  2. Pingback: Snippets – 29th August 2011 » RISCOSitory

  3. Jason

    Hi Mike, had to comment out the test UART to get it to compile as simple_uart.vhd is missing in the source zip. Thinking about adding disk controller support as it aligns with another project that was on the back burner. Nice work.

  4. Mike Post author

    Thanks for the heads up – the project is managed in a git repository and I never recompiled it after I did the export. I will upload a fixed version when I get chance, although it isn’t a necessary part of the design as you discovered.

  5. John Kortink

    The white noise LFSR is incorrect. The tapped bits on the 76489 are 0 and 1. I.e. simply (in Verilog) :

    always @(posedge clk)
    sr[14:0] <= {sr[0] ^ sr[1], sr[14:1]};

    where the reset value is 15'b100000000000000.

    I suppose the error in the logic is the result of opportunistic cut-and-paste, but even the comment mentions that the taps are for an entirely different chip …

  6. Mike Post author

    Hi. Thanks for the fix. The 76489 block was just lifted from FPGA Arcade and it does need some work (it fails timing on Altera). I was aiming to rewrite it at some point and I’ll make sure the tap positions get updated.

  7. MikeJ

    Mike,
    Nice work. Could you drop me a mail, I would like to merge your bug fixes pack into the FPGAArcade code if you don’t mind. I am also bringing up your design on the new Replay board which is fun.

    Best,
    Mike

  8. Jason

    Hi Mike, I’m not sure if there is a field bug in the 6845. My ‘scope has field selection and won’t lock on, and one of my LCDs is also having some kind of interlace issue. I’ll take it in to the office and put it onto the DSO so I can take a closer look. FYI: I put a PAL S-video encoder into my build. With a passive combiner, I get colour on a regular TV with composite in 🙂

  9. Mike Post author

    Hi Jason. The CRTC model doesn’t implement v_total_adjust, so the frame length is going to be slightly shorter than it should be. Although the CRT TV I was testing on had absolutely no problem with this, I can imagine it could upset a flat screen. There are also no serration pulses – just a half line VSYNC delay.

    Nice work on the PAL encoder. Is it open source?

  10. Jason

    Hi Mike. I’m guessing it’s one of these two. Maybe I’ll try to add those bits in. Yes, my composite stuff is based on the open source Joerg Wolfram fbas_encoder and scoops the RGBHV directly from the Video ULA and needs a 32MHz clock. I was going to make a patch which was run-time switchable but there are no dev board switches free so mine drops your existing output scheme. It also occured to me that the video ULA could be tweaked to give proper 16 colours in mode 2 as we’re not limited to TTL RGB monitor.

  11. Graeme

    Hi Mike,
    First can I say what a remarkable achievment. I compiled the code tonight. loaded the roms to flash and it works!!

    I have a problem thou. On the monitor I have, the video blanks at an interval of around 1s. Im guessing at this early stage it’s a timming issue.
    I can run games such as Arcadians and they don’t crash when the display wobbles. I tried on an older crt monitor and it won’t sync at all. Any ideas where I should investigate?

    I’ve also run your spectrum and It’s ace as well.
    Your clearly a very lalented person. 🙂 🙂

  12. Mike Post author

    Hi Graeme. You’re not the only one having timing issues with the video, which is strange because it was rock-solid on both the CRT and LCD that I tested it on (the video is shot from an LCD), although as was often the case with 80s computers, the timing isn’t bang-on BT.601. You aren’t trying to run it into a VGA monitor are you? The Spectrum design has a scan doubler, but the BBC doesn’t so it needs a TV.

  13. Graeme

    That explains that then. Yes that’s what I’ve done. I just hooked it to the PC input on my telly. I’ll wire it to the scart input and let you know how I get on. Thanks.

  14. Stephen

    Mike,

    I managed to get this up and running on the Digilent Atlys. Also having issues with the video. Seems the LCD monitor is not very happy when in mode 3,6 and 7 but is fine in other modes.

    In order to get it working in the other modes i had to use a 640×512@50Hhz signal using the following modeline..

    Modeline “640×512” 32 640 784 912 1024 512 544 548 624 -hsync +vsync

    I then used this pixel clock as my base clock.

    Hope this is of some help.

  15. Stephen

    Mike, quick update. I’ve investigated and found that in modes 3,6 and 7 the 6845 model is not inserting the blank scanlines. This means that the VSYNC pulse is getting sent around PAL scanline 599 on those modes instead of scanline 623 on the other modes. I’ve not seen anything in the code yet that explains it but that would be why many people are reporting problems with syncing. Also it means that the machine doesnt get enough CPU time per frame for some of the more exotic games.

    I spotted this because i’m having to convolve my signal onto a DVI carrier as the Atlys doesnt have VGA. Just HDMI.

  16. Mark

    Wow – just discovered this and your speccy project! Looks like you’ve done some impressive work – more than my half-completed efforts! Nice!

    Also had no idea there was a PAL/NTSC core… my colleague has been working on one and is almost there… he’ll be interested in that no doubt!

  17. Stephen

    Minor modification to the CRTC.. I needed to stop the half line phase shift on alternate frames.

    I basically write a byte to a fifo on every vid_clken, when the fifo has 4 bytes i write that to DDR ram (via Xilinx MIG). The reading bit is trickier but it does scandouble although i havent done the deinterlace properly yet. Thats only *really* important in mode 7.

    Its outputing via HDMI on the Atlys but it could easily be modified to output to VGA on something else.

    I’m now working on getting a Tube interface working. I’ll keep you updated.

  18. Stephen

    After a fair bit of messing about i have a working tube model that is compatible with your FPGA setup. Using it will require an FPGA capable of running a second 65C02 and will need 2K rom + 64K RAM. the major bonus is that we get more ram space free for basic programs.

    Send me an email Mike and i’ll send you over the code i have. current version uses a Xilinx FIFO but im sure we can invent something for the Alteras.

  19. Stephen

    Latest tube model emailed to you mike.

    Everything seems to work ok except 2nd processor elite. Need to investigate why that is crashing.

  20. Frank

    Hi Mike,

    Thank you for publishing this great project! I have got your BBC design working on my DE1 board -except the display. I can tell the BBC is booting and running ok by typing SOUND commands, ‘ blind’ However, I don’t quite understand how you have connected your SCART cable. Could you describe the pin connections VGASCART a bit more please ? Did you use a commercial cable for that, or did you make your own ? Thanks!

  21. Mike Post author

    Hi.
    Sorry for the delay in replying. The cable is home-made. Wiring off the top of my head (so if it doesn’t work, let me know):

      VGA->SCART

    1 -> 15 (red)
    2 -> 11 (green)
    3 -> 7 (blue)
    6 -> 13 (red ground)
    7 -> 9 (green ground)
    8 -> 5 (blue ground)
    10 -> 17 (sync ground)
    13 -> 20 (csync)
    14 -> 16 (select RGB input)

      AUDIO->SCART

    tip(left) -> 6
    ring(right) -> 2
    GND -> 4

    The grounds don’t have to be separate. I will try to find time to check this tomorrow and draw a diagram.

    Mike

  22. Stephen

    Mike,

    Can you try the following for me on your FPGA model.

    *FX 9,0

    This seems to cause a hard interrupt lock up for me about a 10th of a second after i do it. This is whats breaking elite tube for me.

  23. Windfall

    BBC beeps and seems to respond to keyboard, but I’m getting no display on two monitors and two TVs via various cables :sad:. Any way you can build in a switch for interlaced/non-interlaced video ? Otherwise, getting a display from this thing seems to be a form of masochism.

  24. Mike Post author

    I think there’s a VDU command to do that, which shouldn’t be too hard to type blind. You mentioned monitors – you aren’t trying to feed it into a VGA input are you? Unlike the Speccy, the Beeb design doesn’t include a scan doubler so it will only drive a PAL TV/monitor for now. You need to make a VGA to SCART lead like the one for Minimig.

  25. g

    The Proton wasn’t the US version of the BBC Micro; it was a prototype that turned into the BBC Micro. (Acorn’s previous machine was called the Atom. A later one was called the Electron. Spot the theme.)

  26. Mike Post author

    Thanks for the heads-up. For some reason I was under the impression that it actually got released under that name outside the UK, but according to wiki it was simply known as the “British Broadcasting Corporation Microcomputer” to avoid a possible trademark infringement on the acronym.

  27. Pingback: BBC Micro on an FPGA « adafruit industries blog

  28. Pingback: Episódio 30 – Os Anos Incríveis: Parte A | Retrocomputaria

  29. Simon Ellwood

    I downloaded the HDL today to get this running and it compiles under the latest Quartus. I have been trying to find a Scart Lead to doctor without success :(. I see Stephens great improvements including the Tube 😀 A these available to download? Is there a scan doubled version for the DE1 yet so I do not need to make the lead?

    Great work by the way. I would like to port this HDL to the Parallella board when it is available and have a Cortex A9 as a second processor to make the fastest BBC micro in history!!!

  30. Mike Post author

    Hi Simon. I think I have Stephen’s Tube code somewhere, but I never ported it, and I guess you want the scan-doubler first. Maybe he’ll pop up in response to this comment! There’s a DE1 scan-doubler in Minimig which might work, but I’m afraid I haven’t done anything more than you see in the archive.

    There would be something nice about an Cortex second processor, given its lineage. I occasionally see ARM UK IPs looking at this – maybe some of the original Acorn team 🙂

  31. Mike Post author

    Yes. See earlier comments by Stephen, who ported it to the Digilent Atlys board and added a scan doubler. Not sure if he published the HDL, but I could pass on a message to him if you can’t find it.

  32. Andrew Burgess

    Hi Mike,

    I’m interested in getting a copy of the BBC Micro code for the Digilent Atlys board. Do you manage to get a copy of Stephen’s code or do you have details of how I can contact him please.

    Thanks

    Andy

  33. Pingback: New vic20 update | WiSo's collector blog

  34. richard broadhurst

    Has anyone tried changing hsync timing with this setup to move the picture horizontally?
    There were a few demos on the beeb that used it: 3d pool 1000 scrolls by orlando and tricky’s rally-x demo on star dot.
    I was thinking that it would be good to handle the horizontal shifting in the 6845 emulation and produce a normal hsync so that the h-scrolling would work on new tvs/monitors.

  35. Mike

    Do you have any details of the timing changes? It should be straightforward to, for example, clamp the hsync to a fixed length and move the extra to front/back porch instead. This should work ok with a modern TV as long as the overall line lengths remain the same.

    I don’t really have any time to look at this at the moment unfortunately, but it sounds like an interesting one.

  36. richard broadhurst

    For each decrement of the h-sync pulse width, the picture on the screen moves right by half a character and vice-versa.
    You can only change it by a few values before it won’t work on some CRTCs. The default width doesn’t work on some CRTCs.
    You only have to EOR #1 the width, but you do have to blank half one side or the other to stop the sides juddering.
    On a real CRTC, it takes a variable number of scan lines (roughtly 8) to align to the new value, but B-Em does it immediately, which works better in some cases, except when you are trying to create waves scrolling up/down the screen.
    I first thought of creating an RGB to HDMI FPGA based converter incorporating this functionality and possibly additional features such as reprogramming the 8/16 palette colours by changing the h-sync pulse width during the “off-screen” time as a slow serial communication.
    I haven’t checked if the h-sync pulse width is even transmitted during this period and have never written any VHDL, so I don’t know how feasible this is.

  37. richard broadhurst

    I know I have already suggested quite a lot of extra work, but there are a couple of recent hardware mods that would be nice to have:
    The Vic chip mod that adds a C64 sound chip to the beeb – some games have been moded to use this.
    The border colour mod that allows the border colour of the screen to be set IIRC uses &FE22, but I could be wrong – used for timing during development (not sure if this is in b-em).
    The windows version of B-Em is the most accurate emulation of most things beeb related that I have found.

  38. Andy

    Hi Mike,

    I’ve managed to get your design working on a Pipistrello board – http://pipistrello.saanlima.com. This has a Xilinx Spartan 6 LX45 on it.

    I have changed ROM and RAM to work internally within the FPGA . I have it working but for some reason when I run Elite about 20 pixels or so of the right hand side of the screen wraps over to the left. I.e the right hand side vertical line of the box is missing and appears next to the left hand box vertical line.

    I’ve played around with all the 6845 and Video ULA settings I can think of but this makes no difference or is just much worse. I’m wondering whether it could be anything to do with the RAM timings ? Which is a strange thing to focus on but its the only real things I’ve made any changes to i.e because its now internal block ram rather than external. For example I needed to change the following section to work with the internal Block RAM and the vid_clken needed to be ‘0’ instead of ‘1’ to get it working at all.

    I’m a complete newby and all of this is probably very unhelpful but if you could give me any idea as to why Elite is wrapping like this that would be great. Other games generally look ok. I’ve also added a video converter so it works on a VGA display and the same problem occurs.

    –Outputs to RAM
    process(clock_32,reset_n)
    variable ram_write : std_logic;
    begin
    ram_write := ram_enable and not cpu_r_nw;

    if reset_n = ‘0’ then
    sram_we <= "0";
    elsif rising_edge(clock_32) then
    — register sram signals to outputs (clock must be at least 2x cpu clock)
    if vid_clken = '0' then
    — fetch data from previous cpu cycle
    sram_we(0) <= ram_write;
    sram_addr <= cpu_a(14 downto 0);
    if ram_write = '1' then
    sram_dq_in <= cpu_do;
    end if;
    else
    — fetch data from previous display cycle
    sram_we <= "0";
    sram_addr <= display_a;
    end if;
    end if;
    end process;

    Many thanks

    Andy

  39. Rodolfo Diego

    Hello mike, Can you help me ? I want to implement your project, but don’t know where to start. estou começando agora, sou universitário.

  40. Mike

    Hi Rodolfo. You will need to obtain a suitable FPGA board first. There are newer versions of the Terasic Altera boards which you should be able to get cheap if you are at university, and the project has already been ported to a number of other boards including some Xilinx based ones (see comments).

  41. Mike

    The ROMs need to be programmed into the flash chip on the board, not on the SD card. You can program the flash chip using the Terasic demo software that comes with the board.

  42. Mike

    Thanks for the heads-up Simon. I don’t really have the time to play with this stuff any more, so I’m really pleased to see others have picked up where I left off. I had a quick look at the thread on stardot and was particularly taken with the MODE 7 stuff – the character rounding looks excellent!

    Mike

  43. Pingback: ZX Spectrum and BBC Micro VHDL on GitHub | Mike's Lab Notes

Leave a Reply

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