Syntax

' -------------------------------------------------------------------------
' Program Description
' -------------------------------------------------------------------------
'
' Uses READ to move values from a DATA table to a variable.  In this
' program, the table data holds segment patterns for a 7-segment LED.

' -------------------------------------------------------------------------
' Device Settings
' -------------------------------------------------------------------------

DEVICE          SX28, OSC4MHZ, TURBO, STACKX, OPTIONX
FREQ            4_000_000
ID              "READ"

' -------------------------------------------------------------------------
' IO Pins
' -------------------------------------------------------------------------

LEDs            VAR     RB                      ' 7-segment display
TRIS_LEDs       VAR     TRIS_B

' -------------------------------------------------------------------------
' Constants
' -------------------------------------------------------------------------

Dash            CON     %01000000

' -------------------------------------------------------------------------
' Variables
' -------------------------------------------------------------------------

value           VAR     Byte                    ' value to display
tmpB1           VAR     Byte                    ' subroutine work var

' =========================================================================
  PROGRAM Start
' =========================================================================

' -------------------------------------------------------------------------
' Subroutine Declarations
' -------------------------------------------------------------------------

PUT_DIGIT       SUB     1

' -------------------------------------------------------------------------
' Program Code
' -------------------------------------------------------------------------

Start:
  TRIS_LEDs = %00000000                         ' make LEDs outputs

Main:
  DO
    FOR value = 0 TO 16                         ' demo values (last invalid)
      LEDs = PUT_DIGIT value                    ' update the display
      PAUSE 500                                 ' pause 1/2 second
    NEXT
  LOOP

' -------------------------------------------------------------------------
' Subroutine Code
' -------------------------------------------------------------------------

' Use: destination = PUT_DIGIT value
' -- converts number in 'value' to 7-segment digit pattern
'    and places it in 'destination'

PUT_DIGIT:
  tmpB1 = __PARAM1                              ' copy value
  IF tmpB1 <= $F THEN                        ' check range
    READ SegMap + tmpB1, tmpB1                  ' read table value
  ELSE
    tmpB1 = Dash                                ' display dash
  ENDIF
  RETURN tmpB1

' =========================================================================
' User Data
' =========================================================================

SegMap:                                         ' segments maps
'        .gfedcba
  DATA  %00111111                               ' 0
  DATA  %00000110                               ' 1
  DATA  %01011011                               ' 2
  DATA  %01001111                               ' 3
  DATA  %01100110                               ' 4
  DATA  %01101101                               ' 5
  DATA  %01111101                               ' 6
  DATA  %00000111                               ' 7
  DATA  %01111111                               ' 8
  DATA  %01100111                               ' 9

  DATA  %01110111                               ' A
  DATA  %01111100                               ' b
  DATA  %00111001                               ' C
  DATA  %01011110                               ' d
  DATA  %01111001                               ' E
  DATA  %01110001                               ' F

' -------------------------------------------------------------------------
' Program Description
' -------------------------------------------------------------------------
'
' This program demonstrates the use of strings in an SX/B program.  As of
' version 1.4, the SX/B READ instruction can accept a variable base and
' offset.  These values may be created by the compiler by specifying the
' label of a stored z-string, or by using an inline string constant.
'
' The subroutine TX_STR accepts the base and offset values of a stored or
' inline string and will transmit them to a connected terminal -- the
' construction of the subroutine allows the string to cross SX page
' boundaries.

' -------------------------------------------------------------------------
' Device Settings
' -------------------------------------------------------------------------

DEVICE          SX28, OSCXT2, TURBO, STACKX, OPTIONX
FREQ            4_000_000
ID              "READ_STR"

' -------------------------------------------------------------------------
' IO Pins
' -------------------------------------------------------------------------

SOut            VAR     RA.0                    ' serial output

' -------------------------------------------------------------------------
' Constants
' -------------------------------------------------------------------------

Baud            CON     "T9600"                 ' use with MAX232/USB2SER

CR              CON     13                      ' carriage return
LF              CON     10                      ' line feed

' -------------------------------------------------------------------------
' Variables
' -------------------------------------------------------------------------

tmpB1           VAR     Byte                    ' subroutine work vars
tmpB2           VAR     Byte
tmpB3           VAR     Byte
tmpB4           VAR     Byte
tmpW1           VAR     Word

' =========================================================================
  PROGRAM Start
' =========================================================================

' -------------------------------------------------------------------------
' Subroutine Declarations
' -------------------------------------------------------------------------

TX_BYTE         SUB     1, 2                    ' transmit byte
TX_STR          SUB     2, 4                    ' transmit string

' -------------------------------------------------------------------------
' Program Code
' -------------------------------------------------------------------------

Start:
  PLP_A = %0001                                 ' pull-up unused pins
  PLP_B = %00000000
  PLP_C = %00000000

Main:
  TX_STR "SX/B makes string output easy!"       ' send inline string
  TX_STR CrLf                                   ' send stored z-string

  TX_STR TestStr, 14                            ' sub-string
  TX_STR CrLf
  TX_STR TestStr, 13, 16                        ' sub-string at offset
  TX_STR CrLf
  TX_STR TestStr, 8, 31
  TX_STR Version
  TX_STR CrLf
  TX_BYTE LF, 2

  PAUSE 1000
  GOTO Main

' -------------------------------------------------------------------------
' Subroutine Code
' -------------------------------------------------------------------------

' Use: TX_BYTE theByte {, count}
' -- transmit "theByte" at "Baud" on "SOut"
' -- optional "count" may be specified (must be > 0)

TX_BYTE:
  tmpB1 = __PARAM1                              ' save byte
  IF __PARAMCNT = 1 THEN                        ' if no count
    tmpB2 = 1                                   '   set to 1
  ELSE                                          ' otherwise
    tmpB2 = __PARAM2                            '   get count
    IF tmpB2 = 0 THEN                           ' do not allow 0
      tmpB2 = 1
    ENDIF
  ENDIF
  DO WHILE tmpB2 > 0                            ' loop through count
    SEROUT SOut, Baud, tmpB1                    ' send the byte
    DEC tmpB2                                   ' decrement count
  LOOP
  RETURN

' -------------------------------------------------------------------------

' Use: TX_STR [string | label] {, count {, offset }}
' -- "string" is an embedded string constant
' -- "label" is DATA statement label for stored z-String
' -- "count" is number of characters to send (0 is entire string)
' -- "offset" is offset from head of string (0 is head)

TX_STR:
  tmpW1 = __WPARAM12                            ' get offset+base
  tmpB3 = 0                                     ' do whole string

  IF __PARAMCNT >= 3 THEN                       ' count specified?
    tmpB3 = __PARAM3                            ' -- yes, get count
  ENDIF

  IF __PARAMCNT = 4 THEN                        ' offset specified?
    tmpW1 = tmpW1 + __PARAM4                    '  -- yes, update it
  ENDIF

  DO
    READ tmpW1, tmpB4                           ' read a character
    IF tmpB4 = 0 THEN EXIT                      ' if 0, string complete
    TX_BYTE tmpB4                               ' send character
    DEC tmpB3                                   ' update count
    IF tmpB3 = 0 THEN EXIT                      ' terminate if done
    INC tmpW1                                   ' point to next character
  LOOP
  RETURN

' =========================================================================
' User Data
' =========================================================================

TestStr:
  DATA "Parallax, Inc.  SX/B Compiler  Version 1.50", 0

Version:
  DATA "1.50", 0

CrLf:
  DATA CR, LF, 0