macross/doc/macros.itr
Michael Steil 98a36557e4 Initial commit from macross.tar.gz
MD5 (macross.tar.gz) = 4ecb4a6e015b11fef043fe78d1eedb61
2014-05-03 22:20:34 -07:00

316 lines
5.5 KiB
Plaintext

;
; potentially popular macros for the macross assembler
;
; 11-Jan-85 cbm converted for Macross from original a65
;
mif (!isDefined(_macros_)) {
define _macros_ = 1
;
; push and pop X and Y registers
;
macro phx {
txa
pha
}
macro plx {
pla
tax
}
macro phy {
tya
pha
}
macro ply {
pla
tay
}
macro call arg {
jsr arg
}
macro return {
rts
}
macro callret arg {
jmp arg ; same as jsr arg; rts
}
macro save arg {
lda arg
pha
}
macro restore arg {
pla
sta arg
}
; ================================================================
; some auxiliary functions for the macros that follow
;
; MAKE-FIRST-BYTE - access low byte for any addressing mode
function makeFirstByte(operand) {
mif (isImmediateMode(operand)) {
freturn(/operand)
} melse {
freturn(operand)
}
}
; MAKE-SECOND-BYTE - access high byte for any addr mode except (post y zzz)
function makeSecondByte(operand) {
mif (isImmediateMode(operand)) {
freturn(?operand)
} melse {
freturn(operand + 1)
}
}
; MAKE-NTH-BYTE - similarly access arbitrary byte
function makeNthByte(operand, n) {
mif (isImmediateMode(operand)) {
freturn((operand >> (8 * (n - 1))) & 0xFF)
} melse {
freturn(operand + n - 1)
}
}
; ================================================================
; MOVM, MOVEB, MOVB, MOVEW, MOVW, CLEARB, and CLEARW
; Note that the args on MOVEx are src,dst as opposed to
; MOVx, which uses dst,src.
;
; MOVM - move multiple
macro movm n, dst, src {
mvariable i
mfor (i=1, i<=n, i++) {
lda makeNthByte(src, i)
sta makeNthByte(dst, i)
}
}
; MOVEB - move byte from src to dst
macro moveb src, dst {
lda src
sta dst
}
; MOVB - for those who like their destination before their source
macro movb dst, src {
lda src
sta dst
}
; MOVEW - move word from src to dst
; works for all addressing moves EXCEPT (post y zzz)
macro movew src, dst {
lda makeFirstByte(src)
sta makeFirstByte(dst)
lda makeSecondByte(src)
sta makeSecondByte(dst)
}
; MOVW - and another with destination before source
; works for all addressing moves EXCEPT (post y zzz)
macro movw dst, src {
lda makeFirstByte(src)
sta makeFirstByte(dst)
lda makeSecondByte(src)
sta makeSecondByte(dst)
}
; CLEARB - zero byte dst
macro clearb dst {
lda #0
sta dst
}
; CLEARW - zero word dst
; works for all addressing modes EXCEPT (post y dst)
macro clearw dst {
lda #0
sta makeFirstByte(dst)
sta makeSecondByte(dst)
}
; ================================================================
; the general macros
;
; MOVWB - move byte SRC to word DST
; works for all addressing modes EXCEPT (post y zzz)
macro movwb dst, src {
lda src
sta makeFirstByte(dst)
lda #0
sta makeSecondByte(dst)
}
; ADDM - add multiple
macro addm n, dst, src, src1 {
mvariable i
clc
mfor (i=1, i<=n, i++) {
lda makeNthByte(src, i)
adc makeNthByte(src1, i)
sta makeNthByte(dst, i)
}
}
; ADDB - byte dst = byte src0 + byte src1
macro addb dst, src0, src1 {
clc
lda src0
adc src1
sta dst
}
; ADDW - word dst = word src0 + word src1
; works for all addressing modes EXCEPT (post y zzz)
macro addw dst, src0, src1 {
clc
lda makeFirstByte(src0)
adc makeFirstByte(src1)
sta makeFirstByte(dst)
lda makeSecondByte(src0)
adc makeSecondByte(src1)
sta makeSecondByte(dst)
}
; ADDWWB - word dst = word src0 + byte src1
; works for all addressing modes EXCEPT (post y zzz)
macro addwwb dst, src0, src1 {
clc
lda makeFirstByte(src0)
adc src1
sta makeFirstByte(dst)
lda makeSecondByte(src0)
adc #0
sta makeSecondByte(dst)
}
; SUBB - byte dst = byte src0 - byte src1
macro subb dst, src0, src1 {
sec
lda src0
sbc src1
sta dst
}
; SUBW - word dst = word src0 - word src1
; works for all addressing modes EXCEPT (post y zzz)
macro subw dst, src0, src1 {
sec
lda makeFirstByte(src0)
sbc makeFirstByte(src1)
sta makeFirstByte(dst)
lda makeSecondByte(src0)
sbc makeSecondByte(src1)
sta makeSecondByte(dst)
}
; SUBWWB - word dst = word src0 - byte src1
; works for all addressing modes EXCEPT (post y zzz)
macro subwwb dst, src0, src1 {
sec
lda makeFirstByte(src0)
sbc src1
sta makeFirstByte(dst)
lda makeSecondByte(src0)
sbc #0
sta makeSecondByte(dst)
}
; ================================================================
; cmpm, cmpb, cmpw
; compare two quantities (arbitrary length, byte, and word)
; set the condition flags following s0-s1
;
macro cmpm n, s0, s1 {
mvariable i
mfor (i=1, i<=n, i++) {
lda makeNthByte(s0, i)
sbc makeNthByte(s1, i)
}
}
macro cmpb s0, s1 {
sec
lda s0
sbc s1
}
macro cmpw s0, s1 {
sec
lda makeFirstByte(s0)
sbc makeFirstByte(s1)
lda makeSecondByte(s0)
sbc makeSecondByte(s1)
}
;
; ASLM - multiply all by 2
macro aslm n, s0 {
mvariable i
asl s0
mfor (i = 2, i <= n, i++) {
rol makeNthByte(s0, i)
}
}
; ================================================================
; asrm, asrb, asrw
; Arithmetic Shift Right (with sign extend).
;
macro asrm n, s0 {
mvariable i = n
lda makeNthByte(s0, i)
cmp #0x80
mwhile (i > 0) {
ror makeNthByte(s0, i--)
}
}
macro asrb s0 {
lda s0
cmp #0x80
ror s0
}
macro asrw s0 {
lda makeSecondByte(s0)
cmp #0x80
ror makeSecondByte(s0)
ror makeFirstByte(s0)
}
; ================================================================
; repeat n {code. . .}
; repeat n instances of code. e.g.,
; repeat 6 {
; lda x[foo]
; sta x[bar]
; inx
; }
; will generate inline code to move 6 bytes
;
macro repeat count, blockToRepeat {
mvariable i = count
mwhile (i-- > 0) {
blockToRepeat
}
}
macro includef fname {
printf("Including %s\n", fname)
include fname
}
} ; *** end -- mif (!isDefined(_macros_)) ***