home *** CD-ROM | disk | FTP | other *** search
- IFND MACRO_I
- MACRO_I equ 1
-
- ;-------------- define a pixel size to both BYTE,WORD and LONG sizes
- DEFINE MACRO
- \1 equ \2
- \1.B equ (\2)/8
- \1.W equ (\2)/16
- \1.L equ (\2)/32
- ENDM
-
- ;-------------- some standard defines
- CSI equ $9b ; 'Control Sequence Indicator'
- ESC equ $1b ; 'ANSI ESCape character'
- VERTICALTAB equ $0b ; 'VERTICAL TABulator' (Eine Zeile Hoch)
- PALID equ $FFFFFFDE ; Anfang Pal-Bildschirm
- CENDVALUE equ $FFFFFFFE ; Ende Copperliste (auch Macro cend)
-
- ;-------------- all registers mask
- ALLREGISTERS REG D0-D7/A0-A6
-
- ;-------------- standard boolean registers
- TRUE equ 1
- FALSE equ 0
- IFND NULL
- NULL equ 0
- ENDC
-
- ;-------------- push/pop all registers on the stack
- PUSHALL MACRO
- pushm d0-d7/a0-a6
- ENDM
-
- PULLALL MACRO
- popm d0-d7/a0-a6
- ENDM
-
- ;-------------- call function \1 (optional: load library \2)
- ;-------------- NOTE: (to my mind) better than DOSCALL and stuff like that
- ;-------------- because a6 is only loaded if necesarry
- ;--------------
- CALL MACRO
- IFEQ NARG-2
- movea.l \2,a6
- ENDC
- jsr (_LVO\1,a6)
- ENDM
-
- ;-------------- print \1 using arguments \2 (optional: dosBase = \3)
- DPRINTF MACRO
- pushm d0-d3/a0-a1/a6
- IFGT NARG-1
- move.l #\2,D2
- ELSE
- moveq #0,d2
- ENDC
- move.l #\1,d1
- IFGT NARG-2
- CALL VPrintf,\3
- ELSE
- CALL VPrintf,<(dosBase,pc)>
- ENDC
- popm d0-d3/a0-a1/a6
- ENDM
-
- ;-------------- branch to \2 if \1 is uppercase
- ;--------------
- IFUCASE MACRO
- cmpi.b #'a',\1
- blo\0 \2
- cmpi.b #'z',\1
- bgt\0 \2
- ENDM
-
- ;-------------- make data register \1 uppercase
- UCASE MACRO
- cmpi.b #'a',\1
- blo.b .UCASE\@
- cmpi.b #'z',\1
- bgt.b .UCASE\@
- subi.b #('a'-'A'),\1
- .UCASE\@
- ENDM
-
- ;-------------- make data register \1 lowercase
- LCASE MACRO
- cmpi.b #'A',\1
- blo.b .LCASE\@
- cmpi.b #'Z',\1
- bgt.b .LCASE\@
- addi.b #('a'-'A'),\1
- .LCASE\@
- ENDM
-
- ;-------------- branch to \2 if \1 is a digit
- IFDIGIT MACRO
- cmpi.b #'0',\1
- blo.b .DIGIT\@
- cmpi.b #'9',\1
- bgt.b .DIGIT\@
- bra \2
- .DIGIT\@
- ENDM
-
- ;-------------- move BPTR \1 to APTR \2 (scratches d0)
- BMOVE MACRO
- move.l \1,d0
- lsl.l #2,d0
- move.l d0,\2
- ENDM
-
- ;-------------- convert BSTR \1 to ASTR \2 (d0.b is set to the string size)
- B2ASTR MACRO
- IFNC '\2','a0'
- push a0
- ENDC
- move.l \1,d0
- lsl.l #2,d0
- movea.l d0,a0
- move.b (a0)+,d0
- IFNC '\2',a0
- move.l a0,\2
- pop a0
- ENDC
- ENDM
-
- ;-------------- some "antique" defines
- exec.base equ 4
- execBase equ 4
- customBase equ $dff000
- custom.chips equ $dff000
-
- ;-------------- cleanup memory area starting at \1, size=\2
- CLEARSECTION MACRO
- pushm a0/d0
- lea \1,a0
- move.l #(\2)-1,d0
- .CLS\@ clr.b (a0)+
- dbra d0,.CLS\@
- popm a0/d0
- ENDM
-
- ;-------------- define an AmigaDOS style version string \1
- VERSION MACRO
- db 0,'$VER: \1',0
- even
- ENDM
-
- BRF MACRO
- IFEQ NARG-3
- tst \1
- ELSE
- tst\3 \1
- ENDC
- beq\0 \2
- ENDM
-
- ;-------------- BRanch\0 to \2 if \1[\3] is TRUE
- BRT MACRO
- IFEQ NARG-3
- tst \1
- ELSE
- tst\3 \1
- ENDC
- bne\0 \2
- ENDM
-
- ;-------------- BRanch\0 to \1 on Low Bit Clear in \2
- BRLBC MACRO
- btst #0,\1
- beq\0 \2
- ENDM
-
- ;-------------- BRanch\0 to \1 on Low Bit Set in \2
- BRLBS MACRO
- btst #0,\1
- bne\0 \2
- ENDM
-
- ;-------------- BRanch\0 to \1 on Bit \1 Set in \2
- BRBS MACRO
- btst \1,\2
- bne\0 \3
- ENDM
-
- ;-------------- BRanch\0 to \1 on Bit \1 Clear in \2
- BRBC MACRO
- btst \1,\2
- beq\0 \3
- ENDM
-
- ;-------------- compare <ea>-values \1,\2 size=\0 ; scratches d0 or \3
- COMPARE MACRO
- IFEQ NARG-3
- move\0 \1,\3
- cmp\0 \2,\3
- ELSE
- move\0 \1,d0
- cmp\0 \2,d0
- ENDC
- ENDM
-
- ;--------------
- ;-------------- branch to \4 if \1 matches \3 any comparison
- ;-------------- possible comparisons are ==, !=, <, <=, >, >=
- BRANCH MACRO ; \1=Wert 1,\2=Condition Code,\3=Wert 2,\4=Label,[\5=Größe Vergleich]
- IFEQ NARG-5
- COMPARE\5 \1,\3
- ELSE
- COMPARE \1,\3
- ENDC
- IFC '\2','=='
- beq\0 \4
- ENDC
- IFC '\2','!='
- bne\0 \4
- ENDC
- IFC '\2','<='
- bls\0 \4
- ENDC
- IFC '\2','<'
- blo\0 \4
- ENDC
- IFC '\2','>='
- bhs\0 \4
- ENDC
- IFC '\2','>'
- bhi\0 \4
- ENDC
- ENDM
-
- ;-------------- openlib \1 and put the base to \2 (version \3)
- OPENLIB MACRO
- lea \1,a1
- IFEQ NARG-3
- moveq #\3,d0
- ELSE
- moveq #0,d0
- ENDC
- CALL OpenLibrary,<(execBase).w>
- move.l d0,\2
- tst.l d0
- ENDM
-
- ;-------------- "save" closing of library \1
- CLOSELIB MACRO
- tst.l \1
- beq.b .Closelib\@
- movea.l \1,a1
- CALL CloseLibrary,<(execBase).w>
- .Closelib\@
- ENDM
-
- ;-------------- clear stack memory sized \1 in stack register \2
- CLEARSTACK MACRO
- movem.l d0/\2,-(sp)
- move.w #(\1)/2-1,d0
- .CLRSTK\@ move.w #0,(\2)+
- dbra d0,.CLRSTK\@
- movem.l (sp)+,d0/\2
- ENDM
-
- ;-------------- create stack sized \1 in stack register \2
- ;-------------- NOTE: this stack has positive offsets, which means you
- ;-------------- can directly access it with STRUCTURE macros
- CREATESTACK MACRO
- link \2,#-\1
- subi.l #\1,\2
- CLEARSTACK \1,\2
- ENDM
-
- ;-------------- remove local stack sized \1 in stack register \2
- ENDSTACK MACRO
- addi.l #\1,\2
- unlk \2
- ENDM
-
- ;-------------- minimal function head for function \1 using register mask \2
- ;-------------- you *MUST* use DONE (or ENDSUB) to end this function;
- ;-------------- else the assembler will give you a warning
- XENTRY MACRO
- IFEQ NARG-2 ; Wenn es 2 Argumente gibt
- \1_regs reg \2 ; Register sichern
- \1 movem.l \1_regs,-(sp) ; Register auf den Stack
- ELSE ; Sonst
- \1 ; Nur den Funktionsnamen definieren
- ENDC ; Ende
- ENTRYohneDONEfür set \1_done
- ENDM
-
- ;-------------- all-purpose function entry macro. Defines function named \1
- ;-------------- saving the registers \2. Optional: stacksize \3, stackregister \4
- ;-------------- you *MUST* use DONE (or ENDSUB) to end this function;
- ;-------------- else the assembler will give you a warning
- ENTRY MACRO
- IFD IS_LINKABLE
- xdef \1
- ENDC
- XENTRY \1,\2
- IFEQ NARG-4
- \1_stksize equ \3
- \1_stkreg equr \4
- CREATESTACK \3,\4
- ENDC
- ENDM
-
- ;-------------- end a function created with ENTRY or XENTRY macros;
- ;-------------- it cleans up the stack (if one exists) and restores the
- ;-------------- saved register list
- ENDSUB MACRO
- IFNC '','\1'
- IFND \1
- FAIL Die Funktion \1 existiert nicht
- ENDC
- IFND \1_done
- \1_done
- ENDC
- ELSE
- .function_done
- ENDC
- IFD \1_stksize
- ENDSTACK \1_stksize,\1_stkreg
- ENDC
- IFD \1_regs
- movem.l (sp)+,\1_regs
- ENDC
- ENDM
-
- ;-------------- same as ENDSUB but returns with RTS
- DONE MACRO
- ENDSUB \1
- rts
- ENDM
-
- ;-------------- same as ENDSUB but returns with RTE
- DONEEXCEPTION MACRO
- ENDSUB \1
- rte
- ENDM
-
- ;-------------- don't use this: internal DEBUG macro
- DEBUGALLOWED MACRO
- IFD DEBUG_MODE
- __DEBUG_VAR
- IFC '\1',''
- DC.L $7F000
- ELSE
- DC.L \1
- ENDC
- ENDC
- ENDM
-
- DEBUG MACRO
- IFD DEBUG_MODE
- move.l a0,-(sp)
- move.l \1,-(sp)
- movea.l (__DEBUG_VAR),a0
- move.l (sp)+,(a0)+
- IFGT NARG-1
- move.l \2,(a0)+
- ENDC
- IFGT NARG-2
- move.l \3,(a0)+
- ENDC
- IFGT NARG-3
- move.l \4,(a0)+
- ENDC
- IFGT NARG-4
- move.l \5,(a0)+
- ENDC
- IFGT NARG-5
- move.l \6,(a0)+
- ENDC
- move.l a0,(__DEBUG_VAR)
- move.l (sp)+,a0
- ENDC
- ENDM
-
- ;-------------- set or clear flag \3 if \1 matches \2 using comparison \3
- SETFLAG MACRO
- COMPARE\0 \1,\3
- IFC '\2','=='
- seq \4
- ENDC
- IFC '\2','!='
- sne \4
- ENDC
- IFC '\2','<='
- sls \4
- ENDC
- IFC '\2','<'
- slo \4
- ENDC
- IFC '\2','>='
- sge \4
- ENDC
- IFC '\2','>'
- sgt \4
- ENDC
- ENDM
-
- ;-------------- BROKEN::::::::::::::::::::::::::::::::::::::::::::::::
- IIF MACRO ;\1=ConditionCode,\2=Befehle
- IIF_FLAG SET 0
- IFC '\1','EQ'
- IIF_FLAG SET 1
- bne.b .iif\@
- ENDC
- IFC '\1','NE'
- IIF_FLAG SET 1
- beq.b .iif\@
- ENDC
- IFC '\1','LS'
- IIF_FLAG SET 1
- bgt.b .iif\@
- ENDC
- IFC '\1','LO'
- IIF_FLAG SET 1
- bge.b .iif\@
- ENDC
- IFC '\1','HS'
- IIF_FLAG SET 1
- blo.b .iif\@
- ENDC
- IFC '\1','HI'
- IIF_FLAG SET 1
- bls.b .iif\@
- ENDC
- IFNE IIF_FLAG-1
- FAIL Ungültiger Conditioncode '\1' für IIF-Makro
- ENDC
- \2
- IFEQ NARG-3
- bra.b .else\@
- .iif\@
- \3 **** BROKEN, DON'T USE ****
- .else\@
- ELSE
- .iif\@
- ENDC
- ENDM
-
- ;-------------- optimized clear for data registers
- CLEAR_DATAREG MACRO
- IFC \*UPPER(\0),.L
- moveq #0,\1
- ELSE
- clr\0 \1
- ENDC
- ENDM
-
- ;-------------- optimized clear for addr registers
- CLEAR_ADDRREG MACRO
- IFC \*UPPER(\0),.B
- clr.b \1,\1
- ELSE
- suba\0 \1,\1
- ENDC
- ENDM
-
- ;-------------- clear Dx/Ax/anything else
- CLEAR_ANYTHING MACRO
- IFNC '','\1'
- IFEQ \*STRLEN(\1)-3
- IFC \*UPPER(\*LEFT(\1,1)),D
- CLEAR_DATAREG\0 \1
- MEXIT
- ENDC
- IFC \*UPPER(\*LEFT(\1,1)),A
- CLEAR_ADDRREG\0 \1
- MEXIT
- ENDC
- ENDC
- clr\0 \1
- ENDC
- ENDM
-
- ;-------------- optimized clear [up to 16 arguments]
- OPTIMIZED_CLEAR MACRO
- CLEAR_ANYTHING\0 \1
- CLEAR_ANYTHING\0 \2
- CLEAR_ANYTHING\0 \3
- CLEAR_ANYTHING\0 \4
- CLEAR_ANYTHING\0 \5
- CLEAR_ANYTHING\0 \6
- CLEAR_ANYTHING\0 \7
- CLEAR_ANYTHING\0 \8
- CLEAR_ANYTHING\0 \9
- CLEAR_ANYTHING\0 \(10)
- CLEAR_ANYTHING\0 \(11)
- CLEAR_ANYTHING\0 \(12)
- CLEAR_ANYTHING\0 \(13)
- CLEAR_ANYTHING\0 \(14)
- CLEAR_ANYTHING\0 \(15)
- CLEAR_ANYTHING\0 \(16)
- ENDM
-
- ;-------------- required, because in exec/macros.i another 'CLEAR' is defined
- CLEAR SETMAC OPTIMIZED_CLEAR
-
- ;-------------- exchange two variables using stack (don't use stack relative args)
- XCHG MACRO ;Op1,Op2
- IFC \*UPPER(\0),.B
- move.w d0,-(sp)
- move.b \1,d0
- move.b \2,\1
- move.b d0,\2
- move.w (sp)+,d0
- ELSE
- move\0 \1,-(sp)
- move\0 \2,\1
- move\0 (sp)+,\2
- ENDC
- ENDM
-
- ;-------------- same as ++/-- in C
- INC MACRO
- addq\0 #1,\1
- ENDM
- DEC MACRO
- subq\0 #1,\1
- ENDM
-
- ;-------------- index calculation for an 2 dimensional array. BROKEN
- ;--------------
- ;-------------- INDEX \1=result,\2=x,\3=xsize,\4=xmin,[\5=xmax,\6=y,\7=ysize,\8=ymin]
- ;--------------
- ;-------------- Dabei ist
- ;--------------
- ;-------------- x/y : Die Elementnummer
- ;-------------- xsize/ysize : Die Größe eines Elements dieses Typs
- ;-------------- xmin/ymin : Der Minimalwert für das Element
- ;-------------- xmax/ymax : Der Maximalwert für das Element
- ;--------------
- ;-------------- Eine eindimensionale Liste ist dabei So aufgebaut
- ;--------------
- ;-------------- [ Element=0, index=xmin, ,offset=0]
- ;-------------- [ Element=1, index=xmin+xsize ,offset=xsize]
- ;-------------- [ Element=2, index=xmin+2*xsize ,offset=2*xsize]
- ;-------------- ...
- ;--------------
- ;-------------- Eine zweidimensionale Liste ist dabei so aufgebaut
- ;--------------
- ;-------------- [ Element=0/0, index=xmin, ,offset=0]
- ;-------------- [ Element=0/1, index=xmin+xsize ,offset=xsize]
- ;-------------- [ Element=0/2, index=xmax+2*xsize ,offset=2*xsize]
- ;-------------- ...
- ;-------------- [ Element=1/0, index=xmin+(xmin-xmax)*xsize ,offset=(xmin-xmax)*xsize]
- ;-------------- ...
- ;--------------
- INDEX MACRO
- move.l #((\2)-(\4))*(\3),\1 ; Result = X-Offset
- ENDM
-
- ;-------------- Verschiedene direkte 'Branch on Condition'-Befehle, die nicht wie
- ;-------------- 'BRANCH' extra-komische Vergleiche anstellen müßen.
- BRNE MACRO
- cmp\4 \1,\2
- bne\0 \3
- ENDM
-
- BREQ MACRO
- cmp\4 \1,\2
- beq\0 \3
- ENDM
-
- BRLO MACRO
- cmp\4 \1,\2
- blo\0 \3
- ENDM
-
- BRLS MACRO
- cmp\4 \1,\2
- bls\0 \3
- ENDM
-
- BRGT MACRO
- cmp\4 \1,\2
- bgt\0 \3
- ENDM
-
- BRGE MACRO
- cmp\4 \1,\2
- bge\0 \3
- ENDM
-
- BREQ0 MACRO
- tst\3 \1
- beq\0 \2
- ENDM
-
- BRNE0 MACRO
- tst\3 \1
- bne\0 \2
- ENDM
-
- ADDO MACRO
- IFC \*LEFT(\1,1),#
- IFLE \*RIGHT(\1,\*STRLEN(\1)-1)-8
- addq\0 \1,\2
- ELSE
- addi\0 \1,\2
- ENDC
- ELSE
- add\0 \1,\2
- ENDC
- ENDM
-
- SUBO MACRO
- IFC \*LEFT(\1,1),#
- IFLE \*RIGHT(\1,\*STRLEN(\1)-1)-8
- subq\0 \1,\2
- ELSE
- subi\0 \1,\2
- ENDC
- ELSE
- sub\0 \1,\2
- ENDC
- ENDM
-
- ;-------------- copy string \1 to string \2 (both arguments Ax)
- STRCPY MACRO ; sourcereg, targetreg
- .strcpy\@ move.b (\1)+,(\2)+
- bne.s .strcpy\@
- ENDM
-
- ;-------------- cpu status bits
- BITDEF CPUSTATE,EXTENDED,4 ; X
- BITDEF CPUSTATE,NEGATIVE,3 ; N
- BITDEF CPUSTATE,ZERO,2 ; Z
- BITDEF CPUSTATE,OVERFLOW,1 ; V
- BITDEF CPUSTATE,CARRY,0 ; C
-
-
- ;-------------- my REMHEAD macro. Only difference to exec/list.i : uses local
- ;-------------- labels
- MYREMHEAD MACRO ; A0-list A1-(destroyed) D0=node
- MOVE.L (A0),A1
- MOVE.L (A1),D0
- BEQ.B .REMHEAD\@
- MOVE.L D0,(A0)
- EXG.L D0,A1
- MOVE.L A0,LN_PRED(A1)
- .REMHEAD\@
- ENDM
-
- ;-------------- define an intuition-style alert()
- DEFINE_ALERT MACRO
- dc.w 10
- dc.b 15,'\1',0,0
- ENDM
-
- ENDC
- ;--------------
-