The BlinkenBone device has several registers and functions ... so we need one of these dry "Reference" pages here. 

Parameters of device BLINKENBONE:


Name             Short  Value          Access     Info
---------------  -----  -------------  ---------  ------------------------------------------------------------------------------------------
name             name   BLINKENBONE    read only  Unique identifier of device
type             type   blinkenbone_c  read only  Type
enabled          en     1              read only  device installed and ready to use?
emulation_speed  es     1              writable   1 = original speed, > 1: faster
verbosity        v      4              writable   1 = fatal, 2 = error, 3 = warning, 4 = info, 5 = debug
base_addr        addr   760200         read only  controller base address in IO page
slot             sl     30             read only  backplane slot #, interrupt priority within one level, 0 = next to CPU
intr_vector      iv     310            read only  interrupt vector address
intr_level       il     6              read only  interrupt bus request level: 4,5,6,7
panel_host       ph     bigfoot        read only  hostname of Blinkenlight server, the computer running the panel .. physical, Java or PiDP11
panel_addr       pa     0              read only  Address of panel in the Blinkenlight server
panel_config     pc     123456         writable   Custom CONFIG register
poll_period      pp     50             writable   Panel switches are polled every so many milliseconds. 0=disable.
update_period    up     10             writable   Panel lamps are updated every so many milliseconds. 0=disable.

 

PDP-11 register map

The BlinkenBone device appears in the PDP-11 I/O page as list of 16 bit registers. Position is given by parameter base_addr.       

  1. First comes a fix block with registers for the device itself. "Fix" means: they are independed of the connected BlinkenBone panel.
  2. Then there's the list of "mapped panel control registers". These are the memory location which give you access to the panels input switches and output lamps. These are highly dependend of the connected panel.

A panel needs much space in the I/O page. Actual register count depends on the panel ... so choose a base address with enough "air" behind. 
For example, the PDP-11/70 panel needs 29 words of I/O page. And the big "PDP-10 KI10" counts for 116 registers.

Default for base address is 760200, in the midst of the "floating" register space, which is defined to end at 763776.

On "enable", the BlinkenBone device dumps out its actual register layout, shown below for the PDP-11/70 panel. 

Fixed BlinkenBone device registers in PDP-11 address space:

 Addr/Bits Reg name       Info
 --------- --------       ----
 760200    PANEL_ICS      Command and Status Register for panel Inputs
     <15>  ERR            Panel not connected, server error
      <7>  IEVNT          Change Event on some input switches, may trigger INT
      <6>  IIE            Interrupt Enable for Input
 760202    PANEL_OCS      Command and Status Register for panel Outputs
     <15>  ERR            Panel not connected, server error
      <7>  OEVNT          Periodic panel Output (lamps) update occured, may trigger INT
      <6>  OIE            Interrupt Enable for Output
    <1:0>  OTSTMODE       panel test mode: 0=normal,1=lamp test,2=full test,3=powerless
 760204    PANEL_IPERIOD  Interval for periodic panel input polling
    <9:0>  IPERIOD        1..1000 millisecs, 0=off, inits to parameter "poll_period_ms"
 760206    PANEL_OPERIOD  Interval for periodic panel output update
    <9:0>  OPERIOD        1..1000 millisecs, 0=off, inits to parameter "update_period_ms"
  760210   PANEL_ICHGREG  Addr of last changed mapped input switch register
  760212   PANEL_CONFIG   User defined bitpattern to tell PDP-11 panel config

 

Detect Panel Switch changes with the "Input" logic

Register PANEL_ICS (Input Command and Status) gives error and status for the input side of BlinkenBone device, which reads out the panels switches periodically. Flag layout is DEC-style.

Flag ERR indicates that we have no connection to the panel, so there are no switches to handle and no mapped input registers for the panel.

The switches are polled from the Blinkenlight server periodically for changes. Polling speed can be set any time with register PANEL_IPERIOD in units of milliseconds. Default value after reset is given by parameter poll_period. There's no need to change polling period from default value 50ms, unless you have very fast fingers.

Bit IEVNT is set if a change in one of the panel switch states is detected. IEVNT is reset on read out (on DATI bus cycle).
The address of the mapped register holding the switch state is captured into register PANEL_ICHGREG then.

If the interrupt enable bit IIE is set, an interrupt is triggered in IEVNT. Vector and bus request level are given by parameters intr_vector and intr_level.

Setting Lamp patterns with the "Output" logic

Register PANEL_OCS (Output Command and Status) gives error and status for the output side.

Flag ERR indicates that we have no connection to the panel, so there are no lamps to handle.

Bitgroup OTSTMODE sets a self test mode:  0=normal,1=lamp test,2=full test,3=powerless

The panel lamps are updated periodically from the mapped registers. Update period is given by PANEL_OPERIOD, with reset value given by parameter update_period. 

After each update cycle flag OEVNT is set, it's cleared on readout of PANEL_OCS.

Bit OIE controls enable of the periodic "output update" interrupt. Vector and bus request level are given by parameters intr_vector+4 and intr_level.

As the timer and interrupt work even without connected panel, you have a small programmable universal timer here.

Other as for the input side, it makes sense to control the lamp update period: you can program animated light patterns, and drive there display speed via interrupt and variable update frequency. 

Or your light effects are changing with PDP-11 execution speed, so the update frequency should be as high as possible.
1kHz (period=1ms) is max, but may cause too much load on the network between BeagleBone and panel server.

As said, communication with a panel server involves network transactions.
This means: switches and lamps can not be updated with PDP-11 execution speed at ~1MHz, they are updated periodically with a slower synchronisation rate.
Keep in mind that routing to the server may involve unreliable WLAN segments, so be speed-conscious.

Accessing panel controls with mapped registers

blinkenbone pdp1170 smallbox 1


Mapped Input Registers: Starting from fixed register PANEL_CONFIG+2, registers are mapped to input controls (=switches and knobs) of the selected panel.
These registers are "read-only" and reflect the state of switches. Number and function of these  registers depend on the connected panel.
Every switch control is mapped at least to a full 16 bit PDP-11 register, whose name is that of the panel control as provided by the panel server.
If a control is more then 16 bit width, more PDP-11 registers are used. Then suffixes "_A_, "_B", "_C_", "_D" are used.
Example: on PDP-11/70, the ADDR switch bank is 22 bit width.
You read switches <15:00> from register "SR_A", and switches <21:16> from "SR_B", bits <5:0>.

Same for the Mapped Output Registers: they follow the panel input registers in address space.
Nothing new here: Writing into one of these puts lamps on and off, with some delay given by the periodic update logic..
Lamp controls wider then 16 bits also get multiple registers.

Controls of panel 0 "11/70" on server "bigfoot" mapped into PDP-11 address space: 

  Addr    In/out  Reg name       Bits     Panel control idx
  ----    ------  --------       ----     -----------------
  760214  input   SR_A           <15:00>  2
  760216  input   SR_B           <21:16>  2
  760220  input   LOAD_ADRS      <0>      3
  760222  input   EXAM           <0>      4
  760224  input   DEPOSIT        <0>      5
  760226  input   CONT           <0>      6
  760230  input   HALT           <0>      7
  760232  input   S_BUS_CYCLE    <0>      8
  760234  input   START          <0>      9
  760236  input   ADDR_SELECT    <2:0>    24
  760240  input   DATA_SELECT    <1:0>    25
  760242  input   PANEL_LOCK     <0>      1
  760244  output  ADDRESS_A      <15:00>  10
  760246  output  ADDRESS_B      <21:16>  10
  760250  output  DATA           <15:00>  11
  760252  output  PARITY_HIGH    <0>      12
  760254  output  PARITY_LOW     <0>      13
  760256  output  PAR_ERR        <0>      14
  760260  output  ADRS_ERR       <0>      15
  760262  output  RUN            <0>      16
  760264  output  PAUSE          <0>      17
  760266  output  MASTER         <0>      18
  760270  output  MMR0_MODE      <1:0>    19
  760272  output  DATA_SPACE     <0>      20
  760274  output  ADDRESSING_16  <0>      21
  760276  output  ADDRESSING_18  <0>      22
  760300  output  ADDRESSING_22  <0>      23

 

Hello Blinkenlight World

And here is the short-most program for the PDP11/70 panel. It just copies the state of 22 SR switches to the 22 ADDR LEDs.


 1                                .title BBHELLO - Short QUniBone BlinkenBone Device Demo
 2                                ; This program exercises a connected PDP11/70 panel.
 3                                ; It copies the state of 22 SR switches to the 22 ADDR LEDs.
 4
 5                                .asect
 6
 7 160200                          bbaddr = 160200         ; BlinkenBone device start addr in I/O page
 8
 9 000000                          . = 0
10 000000 000137 001000            jmp     @#start         ; early emulation started code execution from 0
11
12 000024                          . = 24                  ; If not HALTed: start on power-up
13 000024 001000                   .word   start           ; PC
14 000026 000340                   .word   340             ; PSW with priority level 7
15
16 001000                          . = 1000
17                             start:
18 001000 012705 160200            mov     #bbaddr,r5      ; r5 = panel base addr
19                             loop:
20                                 ; for mapped registers offsets see 11/70 memory dump
21 001004 016500 000014            mov     14(r5),r0       ; get SR switches <15:00>
22 001010 016501 000016            mov     16(r5),r1       ; get SR switches <21:16>
23 001014 010065 000044            mov     r0,44(r5),      ; set ADDR LEDs <15:00>
24 001020 010165 000046            mov     r1,46(r5)       ; set ADDR LEDs <21:16>
25 001024 000767                   br      loop
26                                 ; shorter using PDP-11 address modes:
27 001026 016565 000014 000044     mov     14(r5),44(r5)
28 001034 016565 000016 000046     mov     16(r5),46(r5)
29
30 .end