904 lines
17 KiB
PHP
904 lines
17 KiB
PHP
|
|
element R
|
|
|
|
repeat 32 i:0
|
|
element R#i? : R + i
|
|
end repeat
|
|
|
|
XH? = R27
|
|
XL? = R26
|
|
YH? = R29
|
|
YL? = R28
|
|
ZH? = R31
|
|
ZL? = R30
|
|
|
|
element X
|
|
element Y
|
|
element Z
|
|
|
|
iterate <instr,opcode>, ADC,000111b, ADD,000011b, AND, 001000b, EOR, 001001b, CP,000101b, CPC,000001b, CPSE,000100b, MOV,001011b, MUL,100111b, OR,001010b, SBC,000010b, SUB,000110b
|
|
macro instr? Rd,Rr
|
|
local value,d,r
|
|
value = +Rd
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
d = value metadata 1 - R
|
|
value = +Rr
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
r = value metadata 1 - R
|
|
dw r and 1111b + d shl 4 + (r shr 4) shl 9 + opcode shl 10
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
end macro
|
|
end iterate
|
|
|
|
iterate <instr,opcode>, ADIW,10010110b, SBIW,10010111b
|
|
macro instr? RRd,K
|
|
local value,d
|
|
match Rdh:Rdl,RRd
|
|
value = +Rdl
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
d = value metadata 1 - R
|
|
value = +Rdh
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
if value metadata 1 - R = d + 1
|
|
if d = 24 | d = 26 | d = 28 | d = 30
|
|
value = +K
|
|
if value >= 0 & value <= 63
|
|
dw value and 1111b + ((d-24) shr 1) shl 4 + (value shr 4) shl 6 + opcode shl 8
|
|
else
|
|
err 'immediate value out of range'
|
|
end if
|
|
else
|
|
err 'specified register not allowed for this instruction'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
else match Rd,RRd
|
|
value = +Rd
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
d = value metadata 1 - R
|
|
if d = 24 | d = 26 | d = 28 | d = 30
|
|
value = +K
|
|
if value >= 0 & value <= 63
|
|
dw value and 1111b + ((d-24) shr 1) shl 4 + (value shr 4) shl 6 + opcode shl 8
|
|
else
|
|
err 'immediate value out of range'
|
|
end if
|
|
else
|
|
err 'specified register not allowed for this instruction'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end match
|
|
end macro
|
|
end iterate
|
|
|
|
iterate <instr,opcode>, ANDI,0111b, CPI,0011b, LDI,1110b, ORI,0110b, SBCI,0100b, SBR,0110b, SUBI,0101b
|
|
macro instr? Rd,K
|
|
local value,d
|
|
value = +Rd
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
d = value metadata 1 - R
|
|
if d >= 16
|
|
value = +K
|
|
if value >= -256 & value <= 255
|
|
value = value and 0FFh
|
|
dw value and 1111b + (d-16) shl 4 + (value shr 4) shl 8 + opcode shl 12
|
|
else
|
|
err 'immediate value out of range'
|
|
end if
|
|
else
|
|
err 'specified register not allowed for this instruction'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
end macro
|
|
end iterate
|
|
|
|
iterate <instr,opcode>, ASR,0101b, COM,0000b, DEC,1010b, INC,0011b, LSR,0110b, NEG,0001b, ROR,0111b, SWAP,0010b
|
|
macro instr? Rd
|
|
local value,d
|
|
value = +Rd
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
d = value metadata 1 - R
|
|
dw opcode + d shl 4 + 1001010b shl 9
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
end macro
|
|
end iterate
|
|
|
|
iterate <instr,opcode>, BCLR,1001'0100'1000'1000b, BSET,1001'0100'0000'1000b
|
|
macro instr? s
|
|
local value
|
|
value = +s
|
|
if value >= 0 & value <= 7
|
|
dw opcode + value shl 4
|
|
else
|
|
err 'bit index out of range'
|
|
end if
|
|
end macro
|
|
end iterate
|
|
|
|
iterate <instr,opcode>, BLD,1111100b, BST,1111101b, SBRC,1111110b, SBRS,1111111b
|
|
macro instr? Rd,b
|
|
local value,d
|
|
value = +Rd
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
d = value metadata 1 - R
|
|
value = +b
|
|
if value >= 0 & value <= 7
|
|
dw value + d shl 4 + opcode shl 9
|
|
else
|
|
err 'bit index out of range'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
end macro
|
|
end iterate
|
|
|
|
iterate <instr,opcode>, BRBC,111101b, BRBS,111100b
|
|
macro instr? s,k
|
|
local index,offset
|
|
index = +s
|
|
if index >= 0 & index <= 7
|
|
offset = -($ shr 1 + 1) + k
|
|
if offset >= -64 & offset <= 63
|
|
dw index + (offset and 1111111b) shl 3 + opcode shl 10
|
|
else
|
|
err 'relative jump out of range'
|
|
end if
|
|
else
|
|
err 'bit index out of range'
|
|
end if
|
|
end macro
|
|
end iterate
|
|
|
|
macro BRCC? k
|
|
BRBC 0,k
|
|
end macro
|
|
|
|
macro BRCS? k
|
|
BRBS 0,k
|
|
end macro
|
|
|
|
macro BREQ? k
|
|
BRBS 1,k
|
|
end macro
|
|
|
|
macro BRGE? k
|
|
BRBC 4,k
|
|
end macro
|
|
|
|
macro BRHC? k
|
|
BRBC 5,k
|
|
end macro
|
|
|
|
macro BRHS? k
|
|
BRBS 5,k
|
|
end macro
|
|
|
|
macro BRID? k
|
|
BRBC 7,k
|
|
end macro
|
|
|
|
macro BRIE? k
|
|
BRBS 7,k
|
|
end macro
|
|
|
|
macro BRLO? k
|
|
BRBS 0,k
|
|
end macro
|
|
|
|
macro BRLT? k
|
|
BRBS 4,k
|
|
end macro
|
|
|
|
macro BRMI? k
|
|
BRBS 2,k
|
|
end macro
|
|
|
|
macro BRNE? k
|
|
BRBC 1,k
|
|
end macro
|
|
|
|
macro BRPL? k
|
|
BRBC 2,k
|
|
end macro
|
|
|
|
macro BRSH? k
|
|
BRBC 0,k
|
|
end macro
|
|
|
|
macro BRTC? k
|
|
BRBC 6,k
|
|
end macro
|
|
|
|
macro BRTS? k
|
|
BRBS 6,k
|
|
end macro
|
|
|
|
macro BRVC? k
|
|
BRBC 3,k
|
|
end macro
|
|
|
|
macro BRVS? k
|
|
BRBS 3,k
|
|
end macro
|
|
|
|
macro CALL? k
|
|
local offset
|
|
offset = -($ shr 1 + 1) + k
|
|
if offset >= -2048 & offset <= 2047
|
|
dw offset and (1 shl 12 - 1) + 1101b shl 12
|
|
else
|
|
offset = +k
|
|
if offset >= 0 & offset <= 1 shl 22 - 1
|
|
dw (offset shr 16) and 1 + 111b shl 1 + (offset shr 17) shl 4 + 1001010b shl 9
|
|
dw offset and (1 shl 16 - 1)
|
|
else
|
|
err 'value out of range'
|
|
end if
|
|
end if
|
|
end macro
|
|
|
|
iterate <instr,opcode>, CBI,10011000b, SBI,10011010b, SBIC,10011001b, SBIS,10011011b
|
|
macro instr? A,b
|
|
local reg,index
|
|
reg = +A
|
|
if reg >= 0 & reg <= 31
|
|
index = +b
|
|
if index >= 0 & index <= 7
|
|
dw index + reg shl 3 + opcode shl 8
|
|
else
|
|
err 'bit index out of range'
|
|
end if
|
|
else
|
|
err 'specified register number not allowed'
|
|
end if
|
|
end macro
|
|
end iterate
|
|
|
|
macro CBR? r,K
|
|
ANDI r,$FF-(K)
|
|
end macro
|
|
|
|
macro CLC?
|
|
dw 1001'0100'1000'1000b
|
|
end macro
|
|
|
|
macro CLH?
|
|
dw 1001'0100'1101'1000b
|
|
end macro
|
|
|
|
macro CLI?
|
|
dw 1001'0100'1111'1000b
|
|
end macro
|
|
|
|
macro CLN?
|
|
dw 1001'0100'1010'1000b
|
|
end macro
|
|
|
|
macro CLR? r
|
|
EOR r,r
|
|
end macro
|
|
|
|
macro CLS?
|
|
dw 1001'0100'1100'1000b
|
|
end macro
|
|
|
|
macro CLT?
|
|
dw 1001'0100'1110'1000b
|
|
end macro
|
|
|
|
macro CLV?
|
|
dw 1001'0100'1011'1000b
|
|
end macro
|
|
|
|
macro CLZ?
|
|
dw 1001'0100'1001'1000b
|
|
end macro
|
|
|
|
macro DES? K
|
|
local value
|
|
value = +K
|
|
if value >= 0 & value <= 0x0F
|
|
dw 1011b + value shl 4 + 10010100b shl 8
|
|
else
|
|
err 'value out of range'
|
|
end if
|
|
end macro
|
|
|
|
macro EICALL?
|
|
dw 1001'0101'0001'1001b
|
|
end macro
|
|
|
|
macro EIJMP?
|
|
dw 1001'0100'0001'1001b
|
|
end macro
|
|
|
|
iterate <instr,opcode,opcode2,opcode3>, ELPM,1001'0101'1101'1000b,0110b,0111b, LPM,1001'0101'1100'1000b,0100b,0101b
|
|
macro instr? args&
|
|
local value,d
|
|
match , args
|
|
dw opcode
|
|
else match Rd=, =Z?, args
|
|
value = +Rd
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
d = value metadata 1 - R
|
|
dw opcode2 + d shl 4 + 1001000b shl 9
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
else match Rd=, =Z?+, args
|
|
value = +Rd
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
d = value metadata 1 - R
|
|
dw opcode3 + d shl 4 + 1001000b shl 9
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end match
|
|
end macro
|
|
end iterate
|
|
|
|
iterate <instr,opcode>, FMUL,1100001000b, FMULS,1110000000b, FMULSU,1110001000b
|
|
macro instr? Rd,Rr
|
|
local value,d,r
|
|
value = +Rd
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
d = value metadata 1 - R
|
|
if d >= 16 & d <= 23
|
|
value = +Rr
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
r = value metadata 1 - R
|
|
if r >= 16 & r <= 23
|
|
dw opcode + (r-16) + (d-16) shl 4
|
|
else
|
|
err 'specified register not allowed for this instruction'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
else
|
|
err 'specified register not allowed for this instruction'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
end macro
|
|
end iterate
|
|
|
|
macro ICALL?
|
|
dw 1001'0101'0000'1001b
|
|
end macro
|
|
|
|
macro IJMP?
|
|
dw 1001'0100'0000'1001b
|
|
end macro
|
|
|
|
macro IN? Rd,A
|
|
local value,d
|
|
value = +Rd
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
d = value metadata 1 - R
|
|
value = +A
|
|
if A >= 0 & A <= 63
|
|
dw A and 1111b + d shl 4 + (A shr 4) shl 9 + 10110b shl 11
|
|
else
|
|
err 'address out of range'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
end macro
|
|
|
|
macro JMP? k
|
|
local offset
|
|
offset = -($ shr 1 + 1) + k
|
|
if offset>=-2048 & offset<=2047
|
|
dw offset and 111111111111b + 1100b shl 12
|
|
else
|
|
offset = +k
|
|
if offset>=0 & offset<=1 shl 22 - 1
|
|
dw (offset shr 16) and 1 + 110b shl 1 + (offset shr 17) shl 4 + 1001010b shl 9
|
|
dw offset and (1 shl 16 - 1)
|
|
else
|
|
err 'value out of range'
|
|
end if
|
|
end if
|
|
end macro
|
|
|
|
iterate <instr,opcode>, LAC,0110b, LAS,0101b, LAT,0111b, XCH,0100b
|
|
macro instr? Rw,Rd
|
|
local value,d
|
|
match =Z?, Rw
|
|
value = +Rd
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
d = value metadata 1 - R
|
|
dw opcode + d shl 4 + 1001001b shl 9
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end match
|
|
end macro
|
|
end iterate
|
|
|
|
macro LD? Rd,Rw
|
|
local value,d
|
|
value = +Rd
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
d = value metadata 1 - R
|
|
match =X?, Rw
|
|
dw 1100b + d shl 4 + 1001000b shl 9
|
|
else match =Y?, Rw
|
|
dw 1000b + d shl 4 + 1000000b shl 9
|
|
else match =Z?, Rw
|
|
dw 0000b + d shl 4 + 1000000b shl 9
|
|
else match =X?+, Rw
|
|
dw 1101b + d shl 4 + 1001000b shl 9
|
|
else match =Y?+, Rw
|
|
dw 1001b + d shl 4 + 1001000b shl 9
|
|
else match =Z?+, Rw
|
|
dw 0001b + d shl 4 + 1001000b shl 9
|
|
else match -=X?, Rw
|
|
dw 1110b + d shl 4 + 1001000b shl 9
|
|
else match -=Y?, Rw
|
|
dw 1010b + d shl 4 + 1001000b shl 9
|
|
else match -=Z?, Rw
|
|
dw 0010b + d shl 4 + 1001000b shl 9
|
|
else
|
|
err 'invalid operand'
|
|
end match
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
end macro
|
|
|
|
macro LDD? Rd,Rq
|
|
local value,d,q
|
|
value = +Rd
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
d = value metadata 1 - R
|
|
value = +Rq
|
|
if value relativeto Y
|
|
q = value - Y
|
|
if q >= 0 & q <= 63
|
|
dw q and 111b + 1 shl 3 + d shl 4 + ((q shr 3) and 11b) shl 10 + (q shr 5) shl 13 + 10b shl 14
|
|
else
|
|
err 'value out of range'
|
|
end if
|
|
else if value relativeto Z
|
|
q = value - Z
|
|
if q >= 0 & q <= 63
|
|
dw q and 111b + d shl 4 + ((q shr 3) and 11b) shl 10 + (q shr 5) shl 13 + 10b shl 14
|
|
else
|
|
err 'value out of range'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
end macro
|
|
|
|
macro LDS? Rd,k
|
|
local value,d
|
|
value = +Rd
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
d = value metadata 1 - R
|
|
value = +k
|
|
if value >= 0 & value <= 65535
|
|
dw d shl 4 + 1001000b shl 9
|
|
dw value
|
|
else
|
|
err 'address out of range'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
end macro
|
|
|
|
macro LSL? r
|
|
ADD r,r
|
|
end macro
|
|
|
|
macro MOVW? args&
|
|
local value,d,r
|
|
match Rdh:Rdl=,Rrh:Rrl, args
|
|
value = +Rdl
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
d = value metadata 1 - R
|
|
value = +Rdh
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
if value metadata 1 - R = d + 1 & d and 1 = 0
|
|
value = +Rrl
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
r = value metadata 1 - R
|
|
value = +Rrh
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
if value metadata 1 - R = r + 1 & r and 1 = 0
|
|
dw r shr 1 + (d shr 1) shl 4 + 1 shl 8
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
else match Rd=,Rr,args
|
|
value = +Rd
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
d = value metadata 1 - R
|
|
if d and 1 = 0
|
|
value = +Rr
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
r = value metadata 1 - R
|
|
if r and 1 = 0
|
|
dw r shr 1 + (d shr 1) shl 4 + 1 shl 8
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end match
|
|
end macro
|
|
|
|
iterate <instr,opcode>, MULS,0010b, MULSU,0011b
|
|
macro instr? Rd,Rr
|
|
local value,d,r
|
|
value = +Rd
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
d = value metadata 1 - R
|
|
if d >= 16 & d <= 31
|
|
value = +Rr
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
r = value metadata 1 - R
|
|
if r >= 16 & r <= 31
|
|
dw (r-16) + (d-16) shl 4 + opcode shl 8
|
|
else
|
|
err 'specified register not allowed for this instruction'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
else
|
|
err 'specified register not allowed for this instruction'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
end macro
|
|
end iterate
|
|
|
|
macro NOP?
|
|
dw 0
|
|
end macro
|
|
|
|
macro OUT? A,Rr
|
|
local value,r
|
|
value = +Rr
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
r = value metadata 1 - R
|
|
value = +A
|
|
if A >= 0 & A <= 63
|
|
dw A and 1111b + r shl 4 + (A shr 4) shl 9 + 10111b shl 11
|
|
else
|
|
err 'address out of range'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
end macro
|
|
|
|
iterate <instr,opcode>, POP,000b, PUSH,001b
|
|
macro instr? Rd
|
|
local value,d
|
|
value = +Rd
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
d = value metadata 1 - R
|
|
dw 1111b + d shl 4 + opcode shl 9 + 1001b shl 12
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
end macro
|
|
end iterate
|
|
|
|
iterate <instr,opcode>, RCALL,1101b, RJMP,1100b
|
|
macro instr? k
|
|
local offset
|
|
offset = -($ shr 1 + 1) + k
|
|
if offset>=-2048 & offset<=2047
|
|
dw offset and 111111111111b + opcode shl 12
|
|
else
|
|
err 'relative jump out of range'
|
|
end if
|
|
end macro
|
|
end iterate
|
|
|
|
macro RET?
|
|
dw 1001'0101'0000'1000b
|
|
end macro
|
|
|
|
macro RETI?
|
|
dw 1001'0101'0001'1000b
|
|
end macro
|
|
|
|
macro ROL? r
|
|
ADC r,r
|
|
end macro
|
|
|
|
macro SEC?
|
|
dw 1001'0100'0000'1000b
|
|
end macro
|
|
|
|
macro SEH?
|
|
dw 1001'0100'0101'1000b
|
|
end macro
|
|
|
|
macro SEI?
|
|
dw 1001'0100'0111'1000b
|
|
end macro
|
|
|
|
macro SEN?
|
|
dw 1001'0100'0010'1000b
|
|
end macro
|
|
|
|
macro SER? Rd
|
|
local value,d
|
|
value = +Rd
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
d = value metadata 1 - R
|
|
if d >= 16
|
|
dw 1111b + (d-16) shl 4 + 11101111b shl 8
|
|
else
|
|
err 'specified register not allowed for this instruction'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
end macro
|
|
|
|
macro SES?
|
|
dw 1001'0100'0100'1000b
|
|
end macro
|
|
|
|
macro SET?
|
|
dw 1001'0100'0110'1000b
|
|
end macro
|
|
|
|
macro SEV?
|
|
dw 1001'0100'0011'1000b
|
|
end macro
|
|
|
|
macro SEZ?
|
|
dw 1001'0100'0001'1000b
|
|
end macro
|
|
|
|
macro SLEEP?
|
|
dw 1001'0101'1000'1000b
|
|
end macro
|
|
|
|
macro SPM? args
|
|
match , args
|
|
dw 1001'0101'1110'1000b
|
|
else match =Z?+,args
|
|
dw 1001'0101'1111'1000b
|
|
else
|
|
err 'invalid operand'
|
|
end match
|
|
end macro
|
|
|
|
macro ST? Rw,Rr
|
|
local value,r
|
|
value = +Rr
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
r = value metadata 1 - R
|
|
match =X?, Rw
|
|
dw 1100b + r shl 4 + 1001001b shl 9
|
|
else match =Y?, Rw
|
|
dw 1000b + r shl 4 + 1000001b shl 9
|
|
else match =Z?, Rw
|
|
dw 0000b + r shl 4 + 1000001b shl 9
|
|
else match =X?+, Rw
|
|
dw 1101b + r shl 4 + 1001001b shl 9
|
|
else match =Y?+, Rw
|
|
dw 1001b + r shl 4 + 1001001b shl 9
|
|
else match =Z?+, Rw
|
|
dw 0001b + r shl 4 + 1001001b shl 9
|
|
else match -=X?, Rw
|
|
dw 1110b + r shl 4 + 1001001b shl 9
|
|
else match -=Y?, Rw
|
|
dw 1010b + r shl 4 + 1001001b shl 9
|
|
else match -=Z?, Rw
|
|
dw 0010b + r shl 4 + 1001001b shl 9
|
|
else
|
|
err 'invalid operand'
|
|
end match
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
end macro
|
|
|
|
macro STD? Rq,Rr
|
|
local value,r,q
|
|
value = +Rr
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
r = value metadata 1 - R
|
|
value = +Rq
|
|
if value relativeto Y
|
|
q = value - Y
|
|
if q >= 0 & q <= 63
|
|
dw q and 111b + 1 shl 3 + r shl 4 + 1 shl 9 + ((q shr 3) and 11b) shl 10 + (q shr 5) shl 13 + 10b shl 14
|
|
else
|
|
err 'value out of range'
|
|
end if
|
|
else if value relativeto Z
|
|
q = value - Z
|
|
if q >= 0 & q <= 63
|
|
dw q and 111b + r shl 4 + 1 shl 9 + ((q shr 3) and 11b) shl 10 + (q shr 5) shl 13 + 10b shl 14
|
|
else
|
|
err 'value out of range'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
end macro
|
|
|
|
macro STS? k,Rr
|
|
local value,r
|
|
value = +Rr
|
|
if value metadata 1 relativeto R & value eq value element 1
|
|
r = value metadata 1 - R
|
|
value = +k
|
|
if value >= 0 & value <= 65535
|
|
dw r shl 4 + 1001001b shl 9
|
|
dw value
|
|
else
|
|
err 'address out of range'
|
|
end if
|
|
else
|
|
err 'invalid operand'
|
|
end if
|
|
end macro
|
|
|
|
macro TST? Rd
|
|
AND Rd,Rd
|
|
end macro
|
|
|
|
macro WDR?
|
|
dw 1001'0101'1010'1000b
|
|
end macro
|
|
|
|
macro BREAK? %
|
|
if defined %
|
|
break ; loop control directive
|
|
else
|
|
dw 1001'0101'1001'1000b
|
|
end if
|
|
end macro
|
|
|
|
define __EVAL_BREAK eval 'break %'
|
|
|
|
calminstruction BREAK?
|
|
assemble __EVAL_BREAK
|
|
end calminstruction
|
|
|
|
PC? equ ($ shr 1)
|
|
|
|
calminstruction (label) ? definition&
|
|
local command
|
|
match : command?, definition
|
|
jno other
|
|
match :: command?, definition
|
|
jyes other
|
|
arrange definition, =LABEL label =AT =$ =shr 1
|
|
assemble definition
|
|
assemble command
|
|
exit
|
|
other:
|
|
arrange definition, label definition
|
|
assemble definition
|
|
end calminstruction
|
|
|
|
if defined SRAM_START
|
|
DSEG?.$ = SRAM_START
|
|
else
|
|
DSEG?.$ = 60h
|
|
end if
|
|
|
|
DSEG? = 0
|
|
|
|
define DIRECTIVE DIRECTIVE
|
|
|
|
macro __ORG? addr*
|
|
if ~ DSEG?
|
|
org (addr) shl 1
|
|
else
|
|
org addr
|
|
end if
|
|
end macro
|
|
DIRECTIVE.ORG? equ __ORG
|
|
|
|
macro __EQU? definition&
|
|
match name == value, definition
|
|
name? = value
|
|
else
|
|
err 'invalid definition'
|
|
end match
|
|
end macro
|
|
DIRECTIVE.EQU? equ __EQU
|
|
|
|
macro __DSEG?
|
|
if ~ DSEG?
|
|
virtual at DSEG?.$
|
|
DSEG? = 1
|
|
end if
|
|
end macro
|
|
DIRECTIVE.DSEG? equ __DSEG
|
|
|
|
macro __CSEG?
|
|
if DSEG?
|
|
DSEG?.$ = $
|
|
end virtual
|
|
DSEG? = 0
|
|
end if
|
|
end macro
|
|
DIRECTIVE.CSEG? equ __CSEG
|
|
|
|
calminstruction ? line&
|
|
local command
|
|
match .command, line
|
|
jno pass
|
|
transform command, DIRECTIVE
|
|
jno pass
|
|
assemble command
|
|
exit
|
|
pass:
|
|
assemble line
|
|
end calminstruction
|