X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fca65%2Fobjcode.c;h=d1ab4f6bd781cf3fbb31a56fd3681e320c2a74b4;hb=aa4a7735d7e29defcef036b45e68e4fb7a4ddf91;hp=9ca419c118c8e7ad86f874b4c8c7a376aea2855c;hpb=54a50d9354bbbb7a509b58d84f90a063c86271d7;p=cc65 diff --git a/src/ca65/objcode.c b/src/ca65/objcode.c index 9ca419c11..d1ab4f6bd 100644 --- a/src/ca65/objcode.c +++ b/src/ca65/objcode.c @@ -1,15 +1,15 @@ /*****************************************************************************/ /* */ -/* objcode.c */ +/* objcode.c */ /* */ -/* Objectcode management for the ca65 macroassembler */ +/* Objectcode management for the ca65 macroassembler */ /* */ /* */ /* */ -/* (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 */ @@ -45,7 +45,7 @@ /*****************************************************************************/ -/* Code */ +/* Code */ /*****************************************************************************/ @@ -54,7 +54,7 @@ void Emit0 (unsigned char OPC) /* Emit an instruction with a zero sized operand */ { Fragment* F = GenFragment (FRAG_LITERAL, 1); - F->V.Data [0] = OPC; + F->V.Data[0] = OPC; } @@ -62,8 +62,31 @@ void Emit0 (unsigned char 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; + } } @@ -71,8 +94,32 @@ void Emit1 (unsigned char OPC, ExprNode* 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; + } } @@ -104,42 +151,67 @@ void EmitPCRel (unsigned char OPC, ExprNode* Expr, unsigned Size) -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; - if (Len > sizeof (F->V.Data)) { - Len = sizeof (F->V.Data); - } + /* Determine the length of the next fragment */ + unsigned Len = Size; + if (Len > sizeof (F->V.Data)) { + Len = sizeof (F->V.Data); + } - /* Create a new fragment */ - F = GenFragment (FRAG_LITERAL, Len); + /* Create a new fragment */ + F = GenFragment (FRAG_LITERAL, Len); - /* Copy the data */ - memcpy (F->V.Data, Data, Len); + /* Copy the data */ + memcpy (F->V.Data, Data, Len); - /* Next chunk */ - Data += Len; - Size -= Len; + /* Next chunk */ + Data += Len; + Size -= Len; } } +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; + } } @@ -147,11 +219,25 @@ void EmitByte (ExprNode* 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; + } } @@ -184,14 +270,11 @@ void EmitFill (unsigned long Count) /* Emit Count fill bytes */ { while (Count) { - /* Calculate the size of the next chunk */ - unsigned Chunk = (Count > 0xFFFF)? 0xFFFF : (unsigned) Count; - Count -= Chunk; + /* Calculate the size of the next chunk */ + unsigned Chunk = (Count > 0xFFFF)? 0xFFFF : (unsigned) Count; + Count -= Chunk; - /* Emit one chunk */ - GenFragment (FRAG_FILL, Chunk); + /* Emit one chunk */ + GenFragment (FRAG_FILL, Chunk); } } - - -