65c02 Assembly programming for the BBC Micro B

The BBC Micro was made by Acorn for the UK's public broadcasting system, it was presented as part of the TV show "BBC Micro Live"

The BBC had highly configurable hardware, with support for many external devices, and even non 6502 coprocessors... it's Basic even supported in-line assembly language!

the Model A was the cheaper model, however it's 16k limit will be rather restrictive, so we will be covering the more usable 32k system the Micro B

Model A Model B Master
Cpu 2mhz 6502 2mhz 6502 2mhz 6502
Ram 16k  32k  128k 
Vram Uses internal memory
Resolution 640×256 640×256 640×256
Colors 8 8 8
Sound chip SN76489 (4 channel) SN76489 (4 channel) SN76489 (4 channel)

Video Registers
Write the regsiter you want to set to $FE00
then write the new value to $FE01
RegNum register description
0 Horizontal total
1 Horizontal displayed characters
2 Horizontal sync position
3 Horizontal sync width/Vertical sync time
4 Vertical total
5 Vertical total adjust
6 Vertical displayed characters
7 Vertical sync position
8 Interlace/Display delay/Cursor delay
9 Scan lines per character
10 Cursor start line and blink type
11 Cursor end line
12 Screen start address H
13 Screen start address L (Address /8)
14 Cursor position    H
15 Cursor position    L
16 Light pen position
17 Light pen position
18 Cursor width (BBFW)

Physical Colors
the way Screen Bytes map to visible colors is strangely configurable, they are defined by the "Video ULA palette"... which maps nibbles to colors... if we map colors wrong, the same byte may appear a different color depending if it's on odd or even vertical strips
Color Num EOR Color
0 7 Black
1 6 Red
2 5 Gree
3 4 Yellow
4 3 Blue
5 2 Magenta
6 1 Cyan
7 0 White

Hardware Addresses

From To Purpose Details
$FE00 $FE07 6845 CRTC  Video controller  18
Set these to change screen mode
$FE08 $FE0F 6850 ACIA  Serial controller  20.3
$FE10 $FE1F Serial ULA Serial system chip 20.9
$FE20 $FE2F Video ULA  Video system chip  19 Set these to change screen mode
$FE30 $FE3F 74LS161 Paged ROM selector 21
$FE40 $FE5F 6522  VIA SYSTEM VIA  23 Sound & Keyboard
$FE60 $FE7F 6522  VIA USER VIA 24
$FE80 $FE9F 8271  FDC Floppy disc controller  25.1
$FEA0 $FEBF 68B54 ADLC ECONET controller 25.2
$FEC0 $FEDF uPD7002 Analogue to digital converter 26
$FEE0 $FEFF Tube ULA Tube system interface 27

Sound Controller - SN76489

Port Purpose Bits Details
$FE40 Data Port ----BAAA A=address (0=sound chip, 3=Keyboard) B=new setting for address AAA
$FE41 Command Port 1CCOVVVV CC=channel O=operation (1=volume) V=Value (Volume 15=off)
$FE42
$FE43 Data Direction DDDDDDDD D=Direction (1=Write)

Key Reading
Key reading on the BBC is a little weird and rather poorly documented

Essentially you have to select a row (0-8) and Column (0-9), then read in the state of each key one bit at a time!.. these are both read and written to port $FE4F

 7  6  5  4  3  2  1  0
K R R R C C C C

When Written Bits 0-3 (Marked C) select the Column (0-9) and bits 4-6 (Marked R) select the Row (0-8)... Bit 7 has no purpose

When Read Bit 7 returns the Keystate and bits 6-0 have no purpose


An example working piece of code is shown to the right, it's partially based on the disassemblies of the firmware.

You will need a PrintHex command to show the read  byte to screen.
    LDA #$7F    ;set port A for input on bit 7 others outputs
    STA $FE43 
    LDA #$03    ;stop auto scan
    STA $FE40
    ;    This section may not be needed
    ;LDA #$0F    ;select non-existent keyboard column F (0-9 only!)
    ;STA $FE4F   ;
    ;LDA #$01    ;cancel keyboard interrupt
    ;STA $FE4D   ;   

    ldy #0
KeyNextLine:
    ldx #8
    tya
KeyNextBit:
    pha
        sta $FE4F
        lda $FE4F
        rol
    pla
    rol z_as
    clc
    adc #%00010000
    dex
    bne KeyNextBit
   
    lda z_as
    iny
    sta (z_hl),y
    jsr PrintHex
    tya
    cmp #8
    bne KeyNextLine
   
    LDA #$0B    ;select auto scan of keyboard
    STA $FE40   ;tell VIA
   

Useful Links
Advanced User Guide PDF