Linked from: https://karma-laboratory.com/petridish/2005/04/wp_part_vi_bs2s.html.

'{$STAMP BS2sx}
'{$PBASIC 2.5}

'Author: Pearl Chen (pearl at karma-laboratory.com)
'Date: Mar 3, 2004
'Revisions: like v5 but with faster baud....
'           and like v7 but the rows AND columns are switched


'***** PINS *****
'Columns (negative / anode) 1 through 8 are pins 8 through 15 respectively
'Rows (positive / cathode) A through H are pins 0 through 7


'***** CONSTANTS ******
P            CON      2        'Pause length for how long a row stays lit up
Baudmode     CON      0        'Baudmode for BS2sx @ 125000 bps
SerialPin    CON      16       'Pin 16 is the dedicated serial I/O pin on my Stamp


'***** VARIABLES *******
col     VAR        Byte(8)     'col will be a decimal number coming in from Processing to turn on pins 0-7
row     VAR        Byte        'row will be used as a counter to turn on the pins 8-15



'***** INIT *******
Init:
  DIRS = %1111111111111111       'Set the direction of all pins to output
  OUTS = %0000000000000000       'Init all pins to LOW (off)

  'Start off by waiting for column data from Processsing, don't start until there's something to animate
  'When you get it, respond back with a "1"
  SERIN SerialPin, Baudmode, [WAIT("A"), STR col\8]
  SEROUT SerialPin, Baudmode, ["1"]



'***** MAIN FUNCTION ******
Main:
'The Main function acts like flow control

  SEROUT SerialPin, Baudmode, ["0"]

  'First, get data from Processing via the serial port
  'Give it a window of 2ms, otherwise just keep on row scanning with current data
  SERIN SerialPin, Baudmode, 7, RowScan, [WAIT("A"), STR col\8]

  'If data was received, respond back to Processing with a "1" before row scanning
  SEROUT SerialPin, Baudmode, ["1"]

  GOTO RowScan


'***** SUBROUTINES *******


RowScan:
'RowScan handles the appearance of all the LEDs lit up at once

  FOR row = 0 TO 7              'scan through rows (top to bottom)
    HIGH row                    'turn on row
      OUTH = col(row)           'turn on relevant columns all at once (target pins 8-15 by using OUTH)
      PAUSE P                   'give it some breathing room so it's actually visible
      OUTH = 0                  'turn off all the columns
    LOW row                     'turn off row
  NEXT

  GOTO Main                     'return back to Main to try and rendezvous with new data