Author Topic: SPASM Macros  (Read 6759 times)

0 Members and 1 Guest are viewing this topic.

Offline Galandros

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1140
  • Rating: +42/-10
    • View Profile
SPASM Macros
« on: February 28, 2010, 07:11:37 am »
Macros are like a language that can produce assembly code and ease some tasks (like math tables and other data). See wikipedia topic for better explanation.
SPASM macros can be quite fun (recursing, dynamic including echoed files...).

On the macros itself I have come with these nifty ones:

- var.inc - var allocation
Code: [Select]
;Example usage:
; varloc(tempswaparea)
;player_x = var(1)
;player_y = var(1)
;buffer_bullets = var(128)
;saveSP = var(2)
; varloc(textshadow,128)
;attack = var(1)
;deffence = var(1)
;overflowedvar = var(500) ;this will give a warning on assembling because overflowed the safe ram (on calculator causes RAM Clear, normally)

#macro var(var.size)
 #define var.counter eval(var.counter+var.inc)
 #define var.inc eval(var.size)
 #ifdef var.end
   #if var.counter>var.end
    .error "Variable allocation overflow!"
   #endif
 #endif
 var.counter
#endmacro

#macro varloc(varloc.value,varloc.size)
 #define var.counter eval(varloc.value)
 #define var.inc 0
 #ifdef varloc.size
   #define var.end eval(varloc.value+varloc.size-1)
 #endif
#endmacro
- convhex.inc convert a label, number, equate or define to hexadecimal representation
Code: [Select]
;Example usage:
; .echo convhex(%10000000)
;label:
; .echo convhex(label)

#macro zconvhex(hexn)
#if hex_remain == 0
   "$",return
#else
 #define hex_digit eval(hexn & $0F)
 #define hex_remain eval(hexn/16)
 #ifndef return
   #define return ""
 #endif
    #if hex_digit == 0
      #define hex_char "0"
    #endif
    #if hex_digit == 1
      #define hex_char "1"
    #endif
    #if hex_digit == 2
      #define hex_char "2"
    #endif
    #if hex_digit == 3
      #define hex_char "3"
    #endif
    #if hex_digit == 4
      #define hex_char "4"
    #endif
    #if hex_digit == 5
      #define hex_char "5"
    #endif
    #if hex_digit == 6
      #define hex_char "6"
    #endif
    #if hex_digit == 7
      #define hex_char "7"
    #endif
    #if hex_digit == 8
      #define hex_char "8"
    #endif
    #if hex_digit == 9
      #define hex_char "9"
    #endif
    #if hex_digit == 10
      #define hex_char "A"
    #endif
    #if hex_digit == 11
      #define hex_char "B"
    #endif
    #if hex_digit == 12
      #define hex_char "C"
    #endif
    #if hex_digit == 13
      #define hex_char "D"
    #endif
    #if hex_digit == 14
      #define hex_char "E"
    #endif
    #if hex_digit == 15
      #define hex_char "F"
    #endif

 #define return eval(hex_char,return)
 zconvhex(eval(hex_remain))
#endif
#endmacro

;wrap the main macro up with another macro to clear the global defines to work more times
#macro convhex(zn)
  #define hex_remain -1
  #define return ""
  zconvhex(zn)
#endmacro
- breakpoint.inc, this echo to a text file named breakpoints.txt the address of breakpoints
(you need convhex macro)
Code: [Select]
;breakpoints.inc
;by Galandros

#include "convhex.inc"
#macro BREAKPOINT
 #ifndef BREAK_F
  .echo > breakpoints.txt "\nBreakpoints:\n"
  .echo >> breakpoints.txt convhex($),"\n"
  #define BREAK_F
 #else
  .echo >> breakpoints.txt convhex($),"\n"
 #endif
#endmacro

;Alternatives to break macro name
#define breakpoint() BREAKPOINT
#define .breakpoint BREAKPOINT
- relocation
(this was not made by me, actually)
Code: [Select]
#macro relocate(location)
 #ifdef g_old_location
   .error "You cannot nest relocate blocks!"
 #else
   #define g_old_location eval($)
   #define g_new_location eval(location)
   .org location
 #endif
#endmacro

#macro endrelocate()
 #ifdef g_new_location
   .org $ - g_new_location + g_old_location
   #undefine g_new_location
   #undefine g_old_location
 #else
   .error "No relocate statements corresponds to this endrelocate!"
 #endif
#endmacro

How to use:
1. copy the text to some text file using Notepad, for example.
2. include in the source code with #include macro.inc directive
3. call it within the source code

Notes:
- to see the examples uncomment the lines (simply delete the ";")
- only works on SPASM. I could try TASM compatibility, but meh, SPASM has some many reasons to be used
- I am giving a cookie especially for Eeems. You can use this macros in the ADE. Just give me credit and put in the include file that the macros were given by me (Galandros). You can include in your IDE, just do the same as I wrote before in this line.

More macros will come. I have done convbin (convert equates to binary)
I am going to release a pack of SPASM macros. ;)
You can post your macros, too. Or request macros. I am doing some experiments with SPASM macros because you can do pretty much everything.
Hobbing in calculator projects.

Offline mapar007

  • LV7 Elite (Next: 700)
  • *******
  • Posts: 550
  • Rating: +28/-5
  • The Great Mata Mata
    • View Profile
Re: SPASM Macros
« Reply #1 on: March 29, 2010, 04:24:57 am »
Ooh, yes! Hex labels. Awesome! (when I do .echo $ for breakpointing, I always have to convert the address to hex. Thanks!)

Offline DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55943
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: SPASM Macros
« Reply #2 on: March 29, 2010, 04:42:39 am »
By labels I assume you mean a bit like the TI-BASIC ones, right?

Offline Galandros

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1140
  • Rating: +42/-10
    • View Profile
Re: SPASM Macros
« Reply #3 on: March 29, 2010, 05:32:12 am »
Macros exist for some reason. :P

By labels I assume you mean a bit like the TI-BASIC ones, right?
Not quite. Depends on how you think about it so, yes the functions is a bit like. Assembly labels represent an address of the code. They are useful for having a description what that part of the code does. Labels also works for subroutines.

A closer analogy with BASIC would be if your lines were numbered. The number would represent the address of the code.
« Last Edit: March 29, 2010, 05:35:46 am by Galandros »
Hobbing in calculator projects.

Offline mapar007

  • LV7 Elite (Next: 700)
  • *******
  • Posts: 550
  • Rating: +28/-5
  • The Great Mata Mata
    • View Profile
Re: SPASM Macros
« Reply #4 on: March 29, 2010, 05:56:54 am »
I like to think of 'call label' as function() in other languages. But a label in asm can be a routine address, a data block address, or even just a number. (although the latter is more commonly referred to as 'an equate')

Offline DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55943
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: SPASM Macros
« Reply #5 on: March 29, 2010, 02:33:54 pm »
Aaah ok thanks Galandros, and yeah I knew the jump commands were used to go to another memory address, I was just not really sure if it was to that that the term label was applied

Offline Galandros

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1140
  • Rating: +42/-10
    • View Profile
Re: SPASM Macros
« Reply #6 on: April 02, 2010, 06:49:15 am »
Finally I decided to pack all the macros I worked on. It is not finished, though... But it has cool macros like the ones above.

See attachment.
Hobbing in calculator projects.

Offline Galandros

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1140
  • Rating: +42/-10
    • View Profile
Re: SPASM Macros
« Reply #7 on: June 25, 2010, 07:10:03 am »
A bit related to SPASM and macros is the attach that contain some interesting features of SPASM undocumented or you didn't know before.
Not essential but might be useful for assembly programmers.

I will also update the macros pack.

Until then here are some interesting macros:
(include_once requires latest spasm or include fcreate.inc)
Code: [Select]
#macro include_once(file)
 clr()
 wr("#ifndef ",file,"_INC")
 wr("#define ",file,"_INC")
 wr("#include ",file)
 wr("#endif")
 run()
 clr()
#endmacro
#define .include_once include_once(

#macro align(boundary)
; Sets the current program counter value to the next multiple of boundary.
 .fill boundary-($%boundary)
#endmacro
#define .align align(

#macro pad_str(str, size)

_
.db str
#define str_len eval($- -_)
#if str_len <= size
 .fill size-str_len,' '
 .db 0    ; NULL terminator
#else
 .error "String size is ",str_len-size," character(s) too long."
#endif
#endmacro
#define .pad_str pad_str(

#macro REPEAT(code,times)
#if times==0
#include temp.asm
 .echo > temp.asm ""
#else
 .echo >> temp.asm code,"\n"
 REPEAT(code,eval(times-1))
#endif
#endmacro
#define .repeat REPEAT(
;l:
; .repeat " ld a,1",8
;m:
; .echo m-l
Hobbing in calculator projects.