;#######################################################################;
;       ___      ___   ___  __    ______   .___  ___.     ______.       ;
;      /   \     \  \ /  / |  |  /  __  \  |   \/   |    /      |       ;
;     /  ^  \     \  '  /  |  | |  |  |  | |  \  /  |   |   (---`       ;
;    /  /_\  \     >   <   |  | |  |  |  | |  |\/|  |    \   \          ;
;   /  _____  \   /  .  \  |  | |  `--'  | |  |  |  | .---)   |         ;
;  /__/     \__\ /__/ \__\ |__|  \______/  |__|  |__| |______/          ;
;                                                                       ;
;                The Assembly SDK for Axe programmers                   ;
;                         By Kevin Horowitz                             ;
;                       Last revision:  1.1.2                           ;
;                                                                       ;
;  This template will make it easy to implement real assembly commands  ;
;into Axe Parser so that they can be used just like the native commands ;
;that come with the App.                                                ;
;                                                                       ;
;#######################################################################;

;###################
;#  Library header #
;###################

;You should include "Axe.inc" in your axiom because it contains a lot of useful
;definitions to aid in Axiom development.  If you're using token replacements,
;you should also include "TokenHook.inc".

#include "Axe.inc"
#include "TokenHook.inc"

;All Axioms must start with $DE,$C0:

.dw $C0DE

;####################
;#  Command Fields  #
;####################

;____FIELD 1____
;Description:     Size of the command
;Size:            2 bytes
;Explanation:     A zero here signals the end of the Axiom.

.dw $0000

;____FIELD 2____
;Description:     Shell compatibility
;Size:            1 byte
;Bits:            bit 0 ==> Nostub ASM Compatible
;                 bit 1 ==> Ion Compatible
;                 bit 2 ==> MirageOS Compatible
;                 bit 3 ==> DoorsCS Compatible
;                 bit 4 ==> Application Compatible
;                 bit 5 ==> Axe Framework Compatible

.db $00

;____FIELD 3____
;Description:     Token to match
;Size:            2 bytes
;Explanation:     If its only a 1 byte token, make the second byte 0.
;                 If its a 2 byte token, the prefix token should come first.
;                 Leave $0000 if this can only be called from other commands.

.db $00,$00

;____FIELD 4____
;Description:     Command type
;Size:            1 byte
;Bits:            bit 0 ==> Subroutine instead of inline routine
;                 bit 1 ==> Command requires the r modifier
;                 bit 2 ==> Command requires the rr modifier
;                 bit 3 ==> Additional argument comes before a store token
;                 bit 4 ==> Puts the data pointer in hl (disables auto-replacements)


.db 0

;____FIELD 5____
;Description:     Number of formal arguments (items in parenthesis)
;Size:            1 byte

.db 0

;____FIELD 6____
;Description:     Routine
;Size:            --Unlimited--
;Explanation:
;
;    For expressions with arguments, the last argument is always in HL.  All
;other arguments are pushed onto the stack with the second-to-last argument
;at the front of the stack and the first argument at the end of the stack.
;So if you have N arguments, there should be N-1 items on the stack.  But don't
;forget, if its a subroutine, the return address is still at the front of the
;stack and needs to be pushed back eventually.
;
;    Routines should start with their origin at address $0000.  This is because
;Axe will automatically replace all jumps and calls to address between $0000
;to $3EFF with the relative positions regardless of where the subroutine is added.
;The addresses between $3F00 and $3FFF get replaced by the corresponding Axe
;subroutines defined by the include file.  16 bit load instructions do not
;automatically get replaced with relative labels.
;
;    The following prefixes will change the replacement policy:
;
; $7F         Next instruction is a relative address.
; $40,$Offs   Next instruction is a relative address with an unsigned byte offset.
; $49         Next instruction is an absolute address.
;
;    These prefixes do not get inserted into the final executable so make sure you
;update the origin to compensate for this effect.  This does count as a byte in the
;size of the program though.  I have included a macro to help with this.  All these
;prefixes are of course disabled when bit 4 of the command type parameter is set.
;
;    You will need an assembler that can handle moving origins to easily use
;these automatic replacements.  Some examples are SPASM's .org directive or
;Brass's .relocate directive.  TASM will not work since it's .org does not behave
;correctly.

.org $0000
Insert_Your_Routine

;##################
;#  And repeat... #
;##################

;Repeat this pattern (not including the library header) until all your routines
;are completed.

;###############################
;#  Custom Token Replacements  #
;###############################

;After the end of the Axiom (the terminating $0000) you can list tokens that you
;would like Axe to replace in the program editor.  They should be in the following
;format:

;____FIELD 1____
;Description:     The token hook you want to replace.
;Size:            2 bytes
;Explanation:     See "TokenHook.inc" for a list of tokens.

.dw $0000

;____FIELD 2____
;Description:     Size of the new string
;Size:            1 byte

.db 0

;____FIELD 3____
;Description:     The new string.
;Size:            See above field.
;Explanation:     This is NOT zero terminated!


.db ""

;This is then repeated.  You can have as many token replacements as memory will allow.
;Please note that you cannot replace tokens that Axe already replaces internally.

;################################
;#  Frequently Asked Questions  #
;################################
;
;How do I compile the code?
;
;  The code must be an appvar in ram or archive.  However, if you have it as a
;  program in ram, Axe will kindly convert it to an appvar for you.  Do NOT
;  include the assembly program header ($6DBB). Always use the Axe Library header
;  ($C0DE) instead.
;
;How does Axe do output?
;
;  The HL register is always used as the output.
;
;Can I redefine existing Axe commands?
;
;  No. The parser only looks through the Axioms once all of the original commands
;  have already been searched through.
;
;What if another library uses the same token as I'm using?
;
;  Similar explanation as above.  The commands are searched for in the order that
;  the Axioms were defined in the program.  So if someone else uses the same
;  token, and their Axiom was defined before yours, then their command is found
;  first.  But if the programmer switches the order of the Axioms, yours will be
;  found first.
;
;What ram areas are safe to use?  Can I use shadow registers?
;
;  If at all possible, I would recommend to not use ANY ram for your subroutines.
;  But, if its absolutely necessary, I would recommend using the OP1-OP6 area as
;  that's the location I use for extremely temporary storage.  Make sure to warn if
;  your library commands are interrupt compatible or not.  If they use temporary
;  storage or shadow registers, they are most likely not.
;
;Can I make a command have a different routine for different shells?
;
;  Yes.  Simply define the routines using the same token values but with different
;  shell compatibility field.
;
;Are there any instructions I can't use?
;
;  Do NOT use the useless "ld a,a" instruction or any other register-self loading.
;  If you need a no-op, use a nop.  This is used to indicate the next instruction
;  is a replacement instruction.  I would also recommend to not use any undocumented
;  instruction because not all emulators support these instructions, most notably
;  the one built into the TI-NSpire.
;
;Can you give me some limits?
;
;  Unlimited command sizes.
;  The maximum number of arguments is 6.
;  The maximum number of commands in a single Axiom is 32.
;  Up to 5 Axiom libraries can be included in a single program.
;  Up to 10 Axe Call replacements can be made per command (recursive limit)