/* */
/* */
/* */
-/* (C) 1998-2003 Ullrich von Bassewitz */
-/* Römerstraße 52 */
-/* D-70794 Filderstadt */
-/* EMail: uz@cc65.org */
+/* (C) 1998-2011, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* Emit an instruction with a zero sized operand */
{
Fragment* F = GenFragment (FRAG_LITERAL, 1);
- F->V.Data [0] = OPC;
+ F->V.Data[0] = OPC;
}
void Emit1 (unsigned char OPC, ExprNode* Value)
/* Emit an instruction with an one byte argument */
{
- Emit0 (OPC);
- EmitByte (Value);
+ long V;
+ Fragment* F;
+
+ if (IsEasyConst (Value, &V)) {
+
+ /* Must be in byte range */
+ if (!IsByteRange (V)) {
+ Error ("Range error (%ld not in [0..255])", V);
+ }
+
+ /* Create a literal fragment */
+ F = GenFragment (FRAG_LITERAL, 2);
+ F->V.Data[0] = OPC;
+ F->V.Data[1] = (unsigned char) V;
+ FreeExpr (Value);
+
+ } else {
+
+ /* Emit the opcode */
+ Emit0 (OPC);
+
+ /* Emit the argument as an expression */
+ F = GenFragment (FRAG_EXPR, 1);
+ F->V.Expr = Value;
+ }
}
void Emit2 (unsigned char OPC, ExprNode* Value)
/* Emit an instruction with a two byte argument */
{
- Emit0 (OPC);
- EmitWord (Value);
+ long V;
+ Fragment* F;
+
+ if (IsEasyConst (Value, &V)) {
+
+ /* Must be in byte range */
+ if (!IsWordRange (V)) {
+ Error ("Range error (%ld not in [0..65535])", V);
+ }
+
+ /* Create a literal fragment */
+ F = GenFragment (FRAG_LITERAL, 3);
+ F->V.Data[0] = OPC;
+ F->V.Data[1] = (unsigned char) V;
+ F->V.Data[2] = (unsigned char) (V >> 8);
+ FreeExpr (Value);
+
+ } else {
+
+ /* Emit the opcode */
+ Emit0 (OPC);
+
+ /* Emit the argument as an expression */
+ F = GenFragment (FRAG_EXPR, 2);
+ F->V.Expr = Value;
+ }
}
-void EmitData (const unsigned char* Data, unsigned Size)
+void EmitData (const void* D, unsigned Size)
/* Emit data into the current segment */
{
+ /* Make a useful pointer from Data */
+ const unsigned char* Data = D;
+
/* Create lots of fragments for the data */
while (Size) {
- Fragment* F;
+ Fragment* F;
- /* Determine the length of the next fragment */
- unsigned Len = Size;
+ /* Determine the length of the next fragment */
+ unsigned Len = Size;
if (Len > sizeof (F->V.Data)) {
Len = sizeof (F->V.Data);
}
+void EmitStrBuf (const StrBuf* Data)
+/* Emit a string into the current segment */
+{
+ /* Use EmitData to output the data */
+ EmitData (SB_GetConstBuf (Data), SB_GetLen (Data));
+}
+
+
+
void EmitByte (ExprNode* Expr)
/* Emit one byte */
{
- /* Create a new fragment */
- Fragment* F = GenFragment (FRAG_EXPR, 1);
-
- /* Set the data */
- F->V.Expr = Expr;
+ long V;
+ Fragment* F;
+
+ if (IsEasyConst (Expr, &V)) {
+ /* Must be in byte range */
+ if (!IsByteRange (V)) {
+ Error ("Range error (%ld not in [0..255])", V);
+ }
+
+ /* Create a literal fragment */
+ F = GenFragment (FRAG_LITERAL, 1);
+ F->V.Data[0] = (unsigned char) V;
+ FreeExpr (Expr);
+ } else {
+ /* Emit the argument as an expression */
+ F = GenFragment (FRAG_EXPR, 1);
+ F->V.Expr = Expr;
+ }
}
void EmitWord (ExprNode* Expr)
/* Emit one word */
{
- /* Create a new fragment */
- Fragment* F = GenFragment (FRAG_EXPR, 2);
-
- /* Set the data */
- F->V.Expr = Expr;
+ long V;
+ Fragment* F;
+
+ if (IsEasyConst (Expr, &V)) {
+ /* Must be in byte range */
+ if (!IsWordRange (V)) {
+ Error ("Range error (%ld not in [0..65535])", V);
+ }
+
+ /* Create a literal fragment */
+ F = GenFragment (FRAG_LITERAL, 2);
+ F->V.Data[0] = (unsigned char) V;
+ F->V.Data[1] = (unsigned char) (V >> 8);
+ FreeExpr (Expr);
+ } else {
+ /* Emit the argument as an expression */
+ Fragment* F = GenFragment (FRAG_EXPR, 2);
+ F->V.Expr = Expr;
+ }
}