]> git.sur5r.net Git - cc65/blobdiff - src/da65/code.c
Added SBC optimizations suggested by Piotr Fusik
[cc65] / src / da65 / code.c
index ff031d0aaecdd9a94a1dbe7326bb5e7b01ccae07..210bb26e9a17d2f2bb23d3ba288a7c6c87ab414e 100644 (file)
 
 
 
-static unsigned char CodeBuf [0x10000];                /* Code buffer */
-static unsigned long CodeStart;                        /* Start address */
-static unsigned long CodeEnd;                  /* End address */
-static unsigned long PC;                       /* Current PC */
+unsigned char CodeBuf [0x10000];       /* Code buffer */
+unsigned long CodeStart;               /* Start address */
+unsigned long CodeEnd;                 /* End address */
+unsigned long PC;                      /* Current PC */
 
 
 
@@ -68,7 +68,7 @@ static unsigned long PC;                      /* Current PC */
 void LoadCode (const char* Name, unsigned long StartAddress)
 /* Load the code from the given file */
 {
-    unsigned Count, MaxCount;
+    long Count, MaxCount, Size;
     FILE* F;
 
 
@@ -80,18 +80,36 @@ void LoadCode (const char* Name, unsigned long StartAddress)
     /* Open the file */
     F = fopen (Name, "rb");
     if (F == 0) {
-       Error ("Cannot open `%s': %s", Name, strerror (errno));
+       Error ("Cannot open `%s': %s", Name, strerror (errno));
+    }
+
+    /* Seek to the end to get the size of the file */
+    if (fseek (F, 0, SEEK_END) != 0) {
+       Error ("Cannot seek on file `%s': %s", Name, strerror (errno));
+    }
+    Size = ftell (F);
+    rewind (F);
+
+    /* Check if the size is larger than what we can read */
+    if (Size == 0) {
+       Error ("File `%s' contains no data", Name);
+    }
+    if (Size > MaxCount) {
+       Warning ("File `%s' is too large, ignoring %ld bytes",
+                Name, Size - MaxCount);
+    } else if (MaxCount > Size) {
+       MaxCount = (unsigned) Size;
     }
 
     /* Read from the file and remember the number of bytes read */
     Count = fread (CodeBuf + StartAddress, 1, MaxCount, F);
-    if (ferror (F)) {
-       Error ("Error reading from `%s': %s", Name, strerror (errno));
-    }
-    if (Count == 0) {
-       Error ("File `%s' contains no data", Name);
+    if (ferror (F) || Count != MaxCount) {
+       Error ("Error reading from `%s': %s", Name, strerror (errno));
     }
 
+    /* Close the file */
+    fclose (F);
+
     /* Set the buffer variables */
     CodeStart = PC = StartAddress;
     CodeEnd = CodeStart + Count - 1;   /* CodeEnd is inclusive */
@@ -99,38 +117,31 @@ void LoadCode (const char* Name, unsigned long StartAddress)
 
 
 
-unsigned GetPC (void)
-/* Get the current program counter */
+unsigned char GetCodeByte (unsigned Addr)
+/* Get a byte from the given address */
 {
-    return PC;
+    PRECONDITION (Addr <= CodeEnd);
+    return CodeBuf [Addr];
 }
 
 
 
-unsigned char PeekCodeByte (void)
-/* Peek at the byte at the current PC */
+unsigned GetCodeWord (unsigned Addr)
+/* Get a word from the given address */
 {
-    PRECONDITION (PC <= CodeEnd);
-    return CodeBuf [PC];
-}
-
-
-
-unsigned char GetCodeByte (void)
-/* Get a byte from the PC and increment it */
-{
-    PRECONDITION (PC <= CodeEnd);
-    return CodeBuf [PC++];
+    unsigned Lo = GetCodeByte (Addr);
+    unsigned Hi = GetCodeByte (Addr+1);
+    return Lo | (Hi << 8);
 }
 
 
 
-unsigned GetCodeWord (void)
-/* Get a word from the current PC and increment it */
+unsigned long GetCodeDWord (unsigned Addr)
+/* Get a dword from the given address */
 {
-    unsigned Lo = GetCodeByte ();
-    unsigned Hi = GetCodeByte ();
-    return Lo | (Hi << 8);
+    unsigned long Lo = GetCodeWord (Addr);
+    unsigned long Hi = GetCodeWord (Addr+2);
+    return Lo | (Hi << 16);
 }
 
 
@@ -139,14 +150,22 @@ unsigned GetRemainingBytes (void)
 /* Return the number of remaining code bytes */
 {
     if (CodeEnd >= PC) {
-       return (CodeEnd - PC + 1);
+       return (CodeEnd - PC + 1);
     } else {
-       return 0;
+       return 0;
     }
 }
 
 
 
+int CodeLeft (void)
+/* Return true if there are code bytes left */
+{
+    return (PC <= CodeEnd);
+}
+
+
+
 void ResetCode (void)
 /* Reset the code input to start over for the next pass */
 {