SX Microcontroler Assembly language Macros

when using the SXKey internal assembler (rather than SASM) if you define a macro and pass it an argument of e.g. $-2, the $ is relative to the start of the macro and in SASM it is relative to the start of the instruction. I believe this is because SASM doesn't evaluate macro parameters until they are used and the SXKey asm evaluates them before the macro is called.

How about setting up a macro that compiles a subroutine inline (with a jump around it) the first time it is used and then sets an equate that causes only the call to the subroutine to be compiled on following calls? See: the massmind NewsLetter:  Issue 0403 for just that AND a great introductions to programming with macros.

Program Templates / Macros

Michael Chadwick [mrchadwickusa(no spam) at yahoo,com] says:

I use the ?(expression) feature of SASM macro processing to display things like how much more room I have left in the first halfof a page.
;-------------------------------------------------------------------------------
; General purpose macros to allow warnings if a page boundary is exceeded
; and to allow the display of variables and calculations at assembly time.
;-------------------------------------------------------------------------------
; Only two are used directly, the others support the evaluation of the 
; variables and expressions.
;===============================================================================
; Requires the use of SASM or it won't work.
;*******************************************************************************
; Use as follows:
; org ISR_BANK
; ..........................
; code etc goes here, the ISR, subroutines etc.
; ..........................
; at the end of the code that must be in the lower half of the bank
; do this:
; checksub ISR_BANK
; it will generate an assembler user warning that the subroutines went past
; the first half of the page by how ever many bytes they did, displayed in hex
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;-------------------------------------------------------------------------------
; may be used with {Text to be displayed goes in here} to generate a warning
; from a text string
warning  MACRO text
  ERROR P1W ?text
  ENDM
;-------------------------------------------------------------------------------
; Basic text display macro that allows multiple arguments.  This is handy
; because SASM macros allow evaluation of an argument as an expression
; by enclosing the expression thus: ?(expression) on the macro invocation
; line.  So we can calculate things and display them as appropriate.
distext  MACRO
  if(\0>=10D)
  warning {\1??\2??\3??\4??\5??\6??\7??\8??\9??\10}
  endif
  if(\0=9)
  warning {\1??\2??\3??\4??\5??\6??\7??\8??\9}
  endif
  if(\0=8)
  warning {\1??\2??\3??\4??\5??\6??\7??\8}
  endif
  if(\0=7)
  warning {\1??\2??\3??\4??\5??\6??\7}
  endif
  if(\0=6)
  warning {\1??\2??\3??\4??\5??\6}
  endif
  if(\0=5)
  warning {\1??\2??\3??\4??\5}
  endif
  if(\0=4)
  warning {\1??\2??\3??\4}
  endif
  if(\0=3)
  warning {\1??\2??\3}
  endif
  if(\0=2)
  warning {\1??\2}
  endif
  if(\0=1)
  warning {\1}
  endif
  ENDM
;-------------------------------------------------------------------------------
;example use of distext to display mixed text and values.
;distext {Current Program Version:SPEM }, ?VERSION_MAJOR, {.}, ?VERSION_MINOR, {.}, ?REVISION, {.}, ?PLATFORM
;-------------------------------------------------------------------------------

;-------------------------------------------------------------------------------
; only used to display the Subroutine warning message with variables
; substituted into the message for the specific program bank
difference MACRO pagestart offset
  warning {pagestart??: Subroutines over by 0x??offset??.}
  ENDM
;-------------------------------------------------------------------------------
; checks if loc is past pagestart + $ff and issues warning if it is
pagetest MACRO loc, pagestart
  IF($??loc > pagestart+$100)
;  make error because the page went too long for subroutines!
  distext {pagestart??: Subroutines over by 0x}, ?($??loc-pagestart-$100), {.}
;  difference pagestart, ?($??loc-pagestart-$100)
  else
  distext pagestart, {is OK.}
  ENDIF
  ENDM
;-------------------------------------------------------------------------------
; Simplifies the use of the rest to give a nicely formated and informative
; warning message to indicate we are past the first half of a page and
; by how much so we can work out how to trim things back
checksub MACRO startofpage
  RADIX HEX
  pagetest ?($), startofpage
  RADIX D
  ENDM
;-------------------------------------------------------------------------------
; Sample macro usage that displays the amount of space left in the first half
; of the current page if any and displays how much over if over.
checkpage MACRO
  RADIX H
  distext {CHECKPAGE: program counter is 0x}, ?($), {.}
  if($&$1ff < $ff)
   distext 0x,?($100-($&$ff)),{ Bytes left in the first half of the page.}
  else
   distext 0x,?(($&$1ff)-$ff),{ Bytes beyond the first half of the page.}
  endif
  RADIX D
  ENDM

I use the following to tell me how far off my ISR frequency is from what I want:

osc equ 50_000_000  ; assume 50 MHz oscillator
ISR_freq equ 614_400  ; 1.627uS
; protocol related constants
; the initial times 10 and subsequent +5 s are
; to force rounding to take place at the proper points
; the final divide by 10 removes the initial factor of 10
; proper ISR rate to produce accurate baud rates is 307200, or 614400.
; actual ISR rate with a 50 Mhz crystal is osc/ISR_count
; percent error is (ISR_real-ISR_freq)*100)/ISR_freq
ISR_count equ ((osc*10/ISR_freq)+5)/10
ISR_real equ osc/ISR_count
; calculate the error to .1% resolution
IF (ISR_real) > ISR_freq)
; Real frequency is too high
ISR_Error equ ((ISR_real-ISR_freq)*1000)/ISR_freq
distext {ISR Frequency is:}, ?(ISR_real), { Hz, high by},{ .}, ?(ISR_Error), {%}
ELSE
; Real frequency is too low
ISR_Error equ ((ISR_freq-ISR_real)*1000)/ISR_freq
distext {ISR Frequency is:}, ?(ISR_real), { Hz, low by},{ .}, ?(ISR_Error), {%}
ENDIF

Of course, if the error gets bigger than .9% the message isn't quite right, but could be fixed with some more IF ELSE constructs. Or maybe I need a macro to generate text from a number with an arbitrary fixed decimal place......

Comments: