LIST ; MEM1.INC Memory Macros, Version 1.0 NOLIST #define _MEM.INC ;********************************************************************** ;* Macros to set/clear/branch/skip on bits ;********************************************************************** ;* Usage Description ;* ----------------------- -------------------------------------- ;* BIT label,file,bit ;Define a bit label ;* SEB label ;set bit using bit label ;* CLB label ;clear bit using bit label ;* SKBS label ;SKIP on bit set ;* SKBC label ;SKIP on bit clear ;* BBS label,address ;BRANCH on bit set ;* BBC label,address ;BRANCH on bit clear ;* CBS label,address ;CALL on bit set ;* CBC label,address ;CALL on bit clear ;* ;* These macros define and use synthetic "bit labels" ;* Bit labels contain the address and bit of a location ;* ;********************************************************************** ;* Static Stack Macros ;********************************************************************** ;* Usage Description ;* ----------------------- -------------------------------------- ;* SSTACK label,size ;Define a static stack at label ;* SRES label,size ;Reserve bytes on the static stack giving it a label ;* SCLR size ;Free bytes from the static stack ;* SPOP ;Pop a byte from the static stack into W ;* SPUSH ;Push a byte from W onto the static stack ;* ;* Note: Note that these macros generate no code, they just manipulate assembler variables. ;* Many of my Macros use these routines to control allocation of temporary variables. ;* The simplest way to use these is to reserve some bytes in memory for the stack, ;* give them a label, and then invoke SSTACK at the start of the main program. ;* ;* Another thing to be aware of is subroutines cannot share a common static ;* stack, but must have their own static stack each. This is because these static ;* stacks reserve and free bytes when the program is assembled. Subroutines are called ;* dynamicly at run time, so these stacks cannot detemine the state of the stack at ;* the time the routine is called. An example of the correct way to do this is; ;* ;* ORG DATASTART ;* stack1 RES 4 ;* stack2 RES 4 ;* ;* ORG RESETVECT ;* start ;* SSTACK stack1,4 ;* ;do something using macros with static-stack temporarys ;* CALL subroutine ;* GOTO start ;* ;* subroutine ;* SSTACK stack2,4 ;* ;do something using macros with static-stack temporarys ;* RETURN ;* ;********************************************************************** DATASTART EQU 0x20 RESETVECT EQU 0x00 INTERVECT EQU 0x04 ;********************************************************************** ;* Macros to set/clear/branch/skip on bits ;********************************************************************** BIT MACRO label,bit,file ;Define a bit label label EQU file<<8|bit ;(macro) ENDM ; SEB MACRO label ;Set bit BSF label>>8,label&7 ;(macro) ENDM ; CLB MACRO label ;Clear bit BCF label>>8,label&7 ;(macro) ENDM ; SBS MACRO label ;Skip on bit set BTFSS label>>8,label&7 ;(macro) ENDM SBC MACRO label ;Skip on bit clear BTFSC label>>8,label&7 ;(macro) ENDM BBS MACRO label,address ;Branch on bit set BTFSC label>>8,label&7 ;(macro) GOTO address ;(macro) ENDM ; BBC MACRO label,address ;Branch on bit clear BTFSS label>>8,label&7 ;(macro) GOTO address ;(macro) ENDM CBS MACRO label,address ;Call on bit set BTFSC label>>8,label&7 ;(macro) CALL address ;(macro) ENDM ; CBC MACRO label,address ;Call on bit clear BTFSS label>>8,label&7 ;(macro) CALL address ;(macro) ENDM ;********************************************************************** ;* Static Stack Macros ;********************************************************************** ;************************************************************** ; Declare a static stack at a label. ; This macro generates no code. ;************************************************************** SSTACK MACRO label,size sstack_beg = label ;Stack start sstack_end = sstack_beg + size ;Stack end sstack_ofs = sstack_beg ;Stack offset ENDM ;************************************************************** ; Reserve bytes on the static stack, giving it a label. ; This macro generates no code. ;************************************************************** SRES MACRO label,size label = sstack_ofs sstack_ofs+=size IF sstack_ofs > sstack_end ERROR "Static stack overflow" ENDIF ENDM ;************************************************************** ; Free bytes from the static stack. ; This macro generates no code. ;************************************************************** SCLR MACRO size sstack_ofs-=size IF sstack_ofs < sstack_beg ERROR "Static stack underflow" ENDIF ENDM ;************************************************************** ; Reserve and push W onto the static stack. ;************************************************************** SPUSH MACRO LOCAL temp SRES temp,1 MOVWF temp ENDM ;************************************************************** ; Free and pop W from the static stack ;************************************************************** SPOP MACRO SCLR 1 MOVF sstack_ofs,W ENDM LIST