1
0
mirror of https://github.com/ksherlock/x65.git synced 2025-02-10 18:31:37 +00:00
x65/macros/x65macro.i
Carl-Henrik Skårstedt 6ffdc3a15e x65macro.i added
- Adding standard macros with for loops, memory copy, add, subtract,
move and set
- macros can be named with dots
- double negatives won't cause errors in expressions
- vice output will convert labels named "debugbreak" to vice breakpoints
rather than vice labels
- fixed issues with mixing conditional operators with math operators in
expressions
2015-12-02 22:16:31 -08:00

517 lines
8.7 KiB
OpenEdge ABL

;x65macros.i
;
; set.b / .w / .t / .l Trg, Value
; - set the contents of an 1-4 byte location to a value
; - uses accumulator
;
; move.b / .w / .t / .l / .n Src,Trg
; - copy 1-4 (or n) bytes from Src location to Trg location
; - uses accumulator
;
; add.n Address1, Address2, Target, Bytes
; - add contents of two memory locations into a target lcoation
; - uses accumulator
;
; sub.n Address1, Address2, Target, Bytes
; - Target = Address1 - Address2
; - uses accumulator
;
; add.ni Address, Value, Target, Bytes
; - add a fixed value to a memory location into a target
; - uses accumulator
;
; sub.ni Address, Value, Target, Bytes
; - Target = Address - Value
; - uses accumulator
;
; addw.i Address, Value, Target
; - Subtract 16 bit Value from contents of Address and store at Target
; - uses accumulator
;
; subw.i Address1, Address2, Target
; - add contents of two 16 bit addresses into a target 16 bit location
; - uses accumulator
;
; mnop Count
; - add Count nops
;
; copy.x Source, Target, Size
; - copy up to 256 bytes using the x register as a counter
; - uses accumulator and x register
;
; copy.y Source, Target, Size
; - copy up to 256 bytes using the y register as a counter
; - uses accumulator and y register
;
; copy.p Src,Trg,Size,PoolZP
; - copy more than 256 bytes using zero page label pool addresses
; - uses accumulator, x and y register
;
; copy.a Src,Trg,Size
; - copy more than 256 bytes using absolute indexed in a loop
; - uses accumulator, x and y register
;
; copy.zp Src,Trg,Size,zpTmp1,zpTmp2
; - copy more than 256 bytes using two pairs of zero page values
; - uses accumulator, x and y register
;
; for.x Start, End
; - iterate using the x register from Start to End, End is not inclusive
; so to iterate from 31 to 0 use for.x 31, -1
; - uses x register
; - end for loop with forend macro
;
; for.y Start, End
; - same as for.x but with the y register
; - uses y register
; - end for loop with forend macro
;
; for.w Start, End, Counter
; - for loop for 16 bit counter
; - uses accumulator
; - end for loop with forend macro
;
; for.ws Start, End, Counter, Step
; - for loop for 16 bit counter with a step value
; - uses accumulator
; - end for loop with forend macro
;
; forend
; - terminates for loops
;
macro set.b Value,Trg
{
lda #Value
sta Trg
}
; Set two bytes to a 16 bit value
macro set.w Value,Trg
{
lda #<Value
sta Trg
lda #>Value
sta Trg+1
}
; Set three bytes to a 24 bit value
macro set.t Value,Trg
{
rept 3 {
lda #Value>>(rept*8)
sta Trg+rept
}
}
; Set three bytes to a 24 bit value
macro set.l Value,Trg
{
rept 4 {
lda #Value>>(rept*8)
sta Trg+rept
}
}
macro move.b Src,Trg
{
lda Src
sta Trg
}
macro move.w Src,Trg
{
rept 2 {
lda Src + rept
sta Trg + rept
}
}
macro move.t Src,Trg
{
rept 3 {
lda Src + rept
sta Trg + rept
}
}
macro move.l Src,Trg
{
rept 4 {
lda Src + rept
sta Trg + rept
}
}
macro move.n Src,Trg,Size
{
rept Size {
lda Src + rept
sta Trg + rept
}
}
; add two numbers together (A and B and Trg are addresses)
macro add.n A,B,Trg,NumSize
{
clc
rept NumSize {
lda A+rept
adc B+rept
sta Trg+rept
}
}
; add two numbers together (A and B and Trg are addresses)
macro sub.n A,B,Trg,NumSize
{
sec
rept NumSize {
lda A+rept
sbc B+rept
sta Trg+rept
}
}
; add a fixed value to an N byte number and store at Trg
macro add.ni Src,Value,Trg,NumSize
{
clc
rept NumSize {
lda Src+rept
adc #Value>>(8*rept)
sta Trg+rept
}
}
; add a fixed value to an N byte number and store at Trg
macro sub.ni Src,Value,Trg,NumSize
{
sec
rept NumSize {
lda Src+rept
sbc #Value>>(8*rept)
sta Trg+rept
}
}
; add a fixed value to a two byte number and store at Trg
macro addw.i Src,Value,Trg
{
clc
lda #<Value
adc Src
sta Trg
lda #>Value
adc Src+1
sta Trg+1
}
; add a fixed value to a two byte number and store at Trg
macro subw.i Src,Value,Trg
{
sec
lda Src
sbc #<Value
sta Trg
lda Src+1
sbc #>Value
sta Trg+1
}
; insert multiple nops
macro mnop Count {
rept Count {
nop
}
}
; copy a fixed length buffer from one place to another
; size is up to a page, changing X and A
macro copy.x Src,Trg,Size
{
if Size==0
elif Size==1
lda Src
sta Trg
elif Size<129
ldx #Size-1
{
lda Src,x
sta Trg,x
dex
bpl !
}
elif Size<256
ldx #0
{
lda Src,x
sta Trg,x
inx
cpx #size
bne !
}
else
error copy.x can only copy up to 256 bytes, use copy.p to copy Size bytes
endif
}
; copy a fixed length buffer from one place to another
; size is up to a page, changing Y and A
macro copy.y Src,Trg,Size
{
if Size==0
elif Size==1
lda Src
sta Trg
elif Size<129
ldy #Size-1
{
lda Src,y
sta Trg,y
dey
bpl !
}
elif Size<256
ldy #0
{
lda Src,y
sta Trg,y
iny
cpy #size
bne !
}
else
error copy.x can only copy up to 256 bytes, use copy.p to copy Size bytes
endif
}
; copy a fixed length buffer using relative zp y indexing
; size is up to a page, changing Y and A
macro copy.ry zpSrcPtr,zpTrgPtr,Size
{
if (Size) > 256
error copy.ry can only copy up to 256 bytes
elif (Size) > 0
ldy #Size-1
{
lda (zpSrcPtr),y
sta (zpTrgPtr),y
dey
if (Size) > 128
cpy #$ff
bne !
else
bpl !
endif
}
endif
}
; copy pages using temp zero page registers
; falls back on CopyF if less than or equal to a page
; changes x, y and A
macro copy.p Src,Trg,Size,PoolZP
{
if (Size<256)
copy.x Src,Trg,Size
else
{
PoolZP zpSrc.w
PoolZP zpTrg.w
set.w zpSrc,Src
set.w zpTrg,Trg
ldx #>Size
ldy #0
{
{
lda (zpSrc),y
sta (zpTrg),y
iny
bne !
}
inc zpSrc+1
inc zpTrg+1
dex
bne !
}
if Size & $ff
ldy #Size-1
{
lda (zpSrc),y
sta (zpTrg),y
dey
if (Size & $ff)<129
bpl !
else
cpy #$ff
bne !
endif
}
endif
}
endif
}
macro copy.zp Src,Trg,Size,zpTmp1,zpTmp2
{
if (Size<256)
copy.x Src,Trg,Size
else
{
set.w zpTmp1,Src
set.w zpTmp2,Trg
ldx #>Size
ldy #0
{
{
lda (zpTmp1),y
sta (zpTmp2),y
iny
bne !
}
inc zpTmp1+1
inc zpTmp2+1
dex
bne !
}
if Size & $ff
ldy #Size-1
{
lda (zpTmp1),y
sta (zpTmp2),y
dey
if (Size & $ff)<129
bpl !
else
cpy #$ff
bne !
endif
}
endif
}
endif
}
macro copy.a Src,Trg,Size
{
if (Size<256)
copy.x Src,Trg,Size
else
{
set.b >Src, ._addr+2
set.b >Trg, ._addr+5
ldy #>Size
ldx #0
._addr
{
{
lda Src,x
sta Trg,x
inx
bne !
}
inc ._addr+2
inc ._addr+5
dey
bne !
}
if Size & $ff
ldx #(Size&$ff)-1
{
lda Src+(Size & $ff00),x
sta Trg+(Size & $ff00),x
dex
if (Size & $ff)<129
bpl !
else
cpx #$ff
bne !
endif
}
endif
}
endif
}
; for (x=start; x<end; x++)
macro for.x Start, End {
ldx #Start
if Start < End
string _ForEnd = "inx\ncpx #End\nbne _ForLoop"
elif Start > End
{
if (-1 == End) & (Start<129)
string _ForEnd = "dex\nbpl _ForLoop"
else
string _ForEnd = "dex\ncpx #End\nbne _ForLoop"
endif
}
else
string _ForEnd = ""
endif
_ForLoop
}
; for (y=start; y<end; y++)
macro for.y Start, End {
ldx #Start
if Start < End
string _ForEnd = "iny\ncpx #End\nbne _ForLoop"
elif Start > End
{
if (-1 == End) & (Start<129)
string _ForEnd = "dey\nbpl _ForLoop"
else
string _ForEnd = "dey\ncpy #End\nbne _ForLoop"
endif
}
else
string _ForEnd = ""
endif
_ForLoop
}
; for (Counter=start; Counter<end; Counter++)
macro for.w Start, End, Counter {
set.w Start, Counter
if (Start) < (End)
string _ForEnd = "{\ninc Counter\nbne %\ninc Counter+1\n}\nlda Counter+1\ncmp #>End\nbne _ForLoop\nlda Counter\ncmp #<End\nbne _ForLoop"
elif (Start) > (End)
string _ForEnd = "{\ndec Counter\nbne %\ndec Counter+1\n}\nlda Counter+1\ncmp #>End\nbne _ForLoop\nlda Counter\ncmp #<End\nbne _ForLoop"
else
string _ForEnd = ""
endif
_ForLoop
}
macro forend {
_ForEnd
undef _ForEnd
}
; for (Counter=start; Counter<end; Counter += Step)
macro for.ws Start, End, Counter, Step {
set.w Start, Counter
if Start < End
if ((Step)<1)
error Step is not a valid iterator for range Start to End
endif
string _ForEnd = "clc\nlda #<Step\nadc Counter\nsta Counter\nlda #>Step\n adc Counter+1\nsta Counter+1\ncmp #>End\nbcc _ForLoop\nlda Counter\ncmp #<End\nbcc _ForLoop"
elif Start > End
if ((Step)>-1)
error Step is not a valid iterator for range Start to End
endif
string _ForEnd = "sec\nlda Counter\n sbc #<(-Step)\nsta Counter\nlda Counter+1\nsbc #>(-Step)\nsta Counter+1\ncmp #(>End)+1\nbcs _ForLoop\nlda Counter\ncmp #(<End)+1\n\nbcs _ForLoop"
else
string _ForEnd = ""
endif
_ForLoop
}
macro forend {
_ForEnd
undef _ForEnd
}