ReadOperand:
;-------------------------------------------------------------------------------
; Check for an immediate value (#expr)
;-------------------------------------------------------------------------------
move.b (a2),d0
cmpi.b #'#',d0
bne.s \TryIndirects
addq.l #1,a2
MACRO_PARAM_END
bsr EvalExpression ; Call MACRO_PARAM_BEGIN/MACRO_PARAM_END
tst.w d1
bmi ErrorExpressionIsNAN
bne ErrorOverflow
move.l d0,OPERAND.Immediate(a5)
move.b #MODE_IMMEDIATE,OPERAND.Mode(a5)
move.b #REG_IMMEDIATE,OPERAND.Reg(a5)
rts
;-------------------------------------------------------------------------------
; Check if the operand begins with - or (
;-------------------------------------------------------------------------------
\TryIndirects:
move.b #MODE_INDIR,OPERAND.Mode(a5) ; Default: (an)
cmpi.b #'-',d0
beq.s \HolyShit
cmpi.b #173,d0
beq.s \HolyShit
cmpi.b #'(',d0
bne.s \EvalAbsolute
bra.s \HolyShit2
;-------------------------------------------------------------------------------
; It could be (an), -(an), (an)+
; This is really a shit, because (\x) could be an absolute, or an indirect
; So we can't use the usual macro replacement, we must be sure that it will
; really be an indirect before performing such a replacement ><
;-------------------------------------------------------------------------------
\HolyShit:
move.b #MODE_PREDEC,OPERAND.Mode(a5)
addq.l #1,a2
cmpi.b #'(',(a2)
bne.s \EvalAbsolute
\HolyShit2:
addq.l #1,a2
MACRO_PARAM_RESTART
movea.l a2,a0
bsr IsAn
tst.b d0
beq ErrorInvalidOperand
MACRO_PARAM_END
cmpi.b #')',(a2)+
bne ErrorInvalidOperand
cmpi.b #'+',(a2)
bne.s \NoPostInc
cmpi.b #MODE_PREDEC,OPERAND.Mode(a5)
beq ErrorInvalidOperand ; It can be predec and postinc in the same time ^^
move.b #MODE_POSTINC,OPERAND.Mode(a5)
\NoPostInc: rts
;-------------------------------------------------------------------------------
; It should be x16, x32, x8(an,yn), x8(pc,yn), x16(an), x16(pc)
;-------------------------------------------------------------------------------
\EvalAbsolute:
bsr EvalExpression
tst.w d1
bmi \TryRegisters
bne ErrorOverflow
MACRO_PARAM_RESTART
cmpi.b #'(',(a2)
beq.s \TryXan
move.b #MODE_ABSOLUTE,OPERAND.Mode(a5)
move.b #REG_ABSOLUTE_LONG,OPERAND.Reg(a5) ; Default: register x32
move.l d0,OPERAND.Absolute(a5)
tst.w OPERAND.Absolute(a5)
bne.s \Long
move.b #REG_ABSOLUTE_SHORT,OPERAND.Reg(a5)
\Long: rts
;-------------------------------------------------------------------------------
; It should be x8(an,yn), x8(pc,yn), x16(an), x16(pc)
;-------------------------------------------------------------------------------
\TryXan:
move.l d0,OPERAND.Offset(a5) ; Save offset for all x(...) address methods. X mut be < 2^16
tst.w OPERAND.Offset(a5)
bne ErrorInvalidOperand
addq.l #1,a2
MACRO_PARAM_RESTART
movea.l a2,a0
bsr IsAn
tst.b d0
beq \TryXpc
MACRO_PARAM_END
cmpi.b #')',(a2)
bne.s \TryXanyn
move.b #MODE_OFFSET,OPERAND.Mode(a5)
move.b d1,OPERAND.Reg(a5)
addq.l #1,a2
rts
\TryXanyn:
move.b #MODE_INDEX,OPERAND.Mode(a5) ; Save addressing method
move.b d1,OPERAND.Reg(a5) ; And an
\CommonBEW:
cmpi.b #',',(a2)+
bne ErrorInvalidOperand
MACRO_PARAM_BEGIN
movea.l a2,a0
bsr IsAn
tas.b d1 ; Set address register in the BEW
tst.b d0
beq.s \SaveBEW
movea.l a2,a0 ; Else it should be a data register
bsr IsDn
tst.b d0
beq ErrorInvalidOperand
\SaveBEW:
lsl.b #4,d1 ; Put the register mask at its place
MACRO_PARAM_END ; Now check for .w/.l. Default to .w
cmpi.b #'.',(a2)
bne.s \EndBEW
addq.l #1,a2
MACRO_PARAM_BEGIN
move.b (a2)+,d0
ori.b #$20,d0 ; Lower case
cmpi.b #'w',d0
beq.s \EndBEW
cmpi.b #'l',d0
bne ErrorInvalidOperand
bset.l #3,d1
\EndBEW:
move.b d1,OPERAND.BEW(a5)
tst.b OPERAND.Offset+1(a5)
bne ErrorInvalidOperand
tst.b OPERAND.Offset+2(a5)
bne ErrorInvalidOperand
MACRO_PARAM_END
cmpi.b #')',(a2)+
bne ErrorInvalidOperand
rts
\TryXpc:
move.b (a2)+,d0
lsl.w #8,d0
move.b (a2)+,d0
ori.w #$2020,d0
cmpi.w #'pc',d0
bne ErrorInvalidOperand
MACRO_PARAM_END
cmpi.b #')',(a2)
bne.s \TryXpcyn
move.b #MODE_PC,OPERAND.Mode(a5)
move.b #REG_PC,OPERAND.Reg(a5)
addq.l #1,a2
rts
\TryXpcyn:
move.b #MODE_PC,OPERAND.Mode(a5)
move.b #REG_PC_INDEX,OPERAND.Reg(a5)
bra \CommonBEW
;-------------------------------------------------------------------------------
; Last possibility: an, dn, usp, ccr, sr
;-------------------------------------------------------------------------------
\TryRegisters:
movea.l a2,a0
bsr IsDn
tst.b d0
beq.s \NoDn
move.b #MODE_DN,OPERAND.Mode(a5)
move.b d1,OPERAND.Reg(a5)
addq.l #2,a2
rts
\NoDn: movea.l a2,a0
bsr IsAn
tst.b d0
beq.s \NoAn
move.b #MODE_AN,OPERAND.Mode(a5)
move.b d1,OPERAND.Reg(a5)
addq.l #2,a2
rts
\NoAn: move.b (a2),d0 ; Read the 2 next chars, and put them in lower case
lsl.w #8,d0
move.b 1(a2),d0
ori.w #$2020,d0
cmpi.w #'sr',d0
bne.s \NoSR
move.b #MODE_SR,OPERAND.Mode(a5)
addq.l #2,a2
rts
\NoSR: cmpi.w #'cc',d0
bne.s \NoCCR
move.b 2(a2),d0
ori.b #$20,d0
cmpi.b #'r',d0
bne.s \NoCCR
move.b #MODE_CCR,OPERAND.Mode(a5)
addq.l #3,a2
rts
\NoCCR: cmpi.w #'us',d0
bne ErrorInvalidOperand
move.b 2(a2),d0
ori.b #$20,d0
cmpi.b #'p',d0
bne ErrorInvalidOperand
move.b #MODE_USP,OPERAND.Mode(a5)
addq.l #3,a2
rts