package org.reasm.m68k.assembly.internal; import java.io.IOException; import javax.annotation.Nonnull; import javax.annotation.concurrent.Immutable; import org.reasm.AssemblyMessage; import org.reasm.Value; import org.reasm.m68k.messages.CountMustNotBeNegativeErrorMessage; import com.google.common.primitives.UnsignedLongs; /** * The <code>DCB</code> directive. * * @author Francis Gagné */ @Immutable class DcbDirective extends Mnemonic { @Nonnull static final DcbDirective DCB = new DcbDirective(); @Nonnull private static final CardinalValueVisitor.ErrorFactory NEGATIVE_VALUE_ERROR_FACTORY = new CardinalValueVisitor.ErrorFactory() { @Override public AssemblyMessage createMessage() { return new CountMustNotBeNegativeErrorMessage(); } }; private DcbDirective() { } @Override void assemble(M68KAssemblyContext context) throws IOException { InstructionSize size = context.parseInstructionSize(); if (size == InstructionSize.INVALID) { context.addInvalidSizeAttributeErrorMessage(); size = InstructionSize.DEFAULT; } if (size != InstructionSize.BYTE) { context.automaticEven(); } if (context.requireNumberOfOperands(2)) { final Value countValue = evaluateExpressionOperand(context, 0); if (countValue != null) { final CardinalValueVisitor countVisitor = context.cardinalValueVisitor; countVisitor.reset(0, NEGATIVE_VALUE_ERROR_FACTORY); Value.accept(countValue, countVisitor); final long count = countVisitor.getValue(); final Value dataValue = evaluateExpressionOperand(context, 1); final DcValueVisitor dataVisitor = context.getDcValueVisitor(size); dataVisitor.reset(size); Value.accept(dataValue, dataVisitor); for (long i = 0; UnsignedLongs.compare(i, count) < 0; i++) { dataVisitor.encode(); } } } } }