Fix checkpatch warnings
[emu8051.git] / src / common / memory.c
index c5b2acf..ec7542a 100644 (file)
@@ -4,21 +4,10 @@
  * Copyright (C) 1999 Jonathan St-AndrĂ©
  * Copyright (C) 1999 Hugo Villeneuve <hugo@hugovil.com>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ * This file is released under the GPLv2
  */
 
+#include <stdbool.h>
 #include <stdio.h>
 #include <string.h>
 
@@ -75,6 +64,41 @@ memory_init(void)
        }
 }
 
+/* Return true if address is valid, false otherwise. */
+int
+memory_check_address(enum mem_id_t id, unsigned long address, int display_error)
+{
+       if (address >= (unsigned long) mem_infos[id].max_size) {
+               if (display_error == DISPLAY_ERROR_YES)
+                       log_err("Address out of range ($%X >= $%X", address,
+                               mem_infos[id].max_size - 1);
+               return false;
+       } else {
+               return true;
+       }
+}
+
+void
+memory_convert_bit_address(uint8_t bit_address, uint8_t *byte_address,
+                          uint8_t *bit_number)
+{
+       if (bit_address > 0x7F) {
+               /* SFR 80-FF */
+               *byte_address = bit_address & 0xF8;
+               *bit_number = bit_address & 0x07;
+       } else {
+               /* 20-2F */
+               *byte_address = (bit_address >> 3) + 0x20;
+               *bit_number = bit_address & 0x07;
+       }
+}
+
+u_int8_t *
+memory_getbuf(enum mem_id_t id, unsigned long address)
+{
+       return &mem_infos[id].buf[address];
+}
+
 void
 memory_clear(enum mem_id_t id)
 {
@@ -84,13 +108,49 @@ memory_clear(enum mem_id_t id)
 void
 memory_write8(enum mem_id_t id, unsigned long address, u_int8_t value)
 {
-       if (address >= mem_infos[id].max_size) {
-               printf("Error writing to memory ID: %d\n", id);
-               printf("  Address (%lu) greater than maximum memory size\n",
-                      address);
+       if (address >= (unsigned long) mem_infos[id].max_size) {
+               log_err("Error writing to memory ID: %d\n"
+                       "  Address (%lu) greater than maximum memory size",
+                       id, address);
                return;
-       } else
+       } else {
                mem_infos[id].buf[address] = value;
+       }
+}
+
+/* Write with a direct addressing mode at Address the new Value */
+void
+memory_write_direct(unsigned int address, unsigned char value)
+{
+       memory_write8(INT_MEM_ID, address, value);
+}
+
+/* Write with an indirect addressing mode at Address the new Value */
+void
+memory_write_indirect(unsigned int address, unsigned char value)
+{
+       if (address > 0x7F) {
+               memory_write8(EXT_MEM_ID, address, value);
+               return;
+       }
+
+       memory_write8(INT_MEM_ID, address, value);
+}
+
+/* Write with a bit addressing mode at BitAddress the new Value */
+void
+memory_write_bit(uint8_t bit_address, uint8_t value)
+{
+       uint8_t byte_address;
+       uint8_t bit_number;
+       unsigned char byte_val, byte_mask;
+
+       memory_convert_bit_address(bit_address, &byte_address, &bit_number);
+
+       byte_mask = ((1 << bit_number) ^ 0xFF);
+       byte_val = memory_read_direct(byte_address) & byte_mask;
+       byte_val += value << bit_number;
+       memory_write_direct(byte_address, byte_val);
 }
 
 void
@@ -110,13 +170,49 @@ memory_sfr_write_dptr(u_int16_t value)
 u_int8_t
 memory_read8(enum mem_id_t id, unsigned long address)
 {
-       if (address >= mem_infos[id].max_size) {
-               printf("Error reading from memory ID: %d\n", id);
-               printf("  Address (%lu) greater than maximum memory size\n",
-                      address);
+       if (address >= (unsigned long) mem_infos[id].max_size) {
+               log_err("Error reading from memory ID: %d\n"
+                       "  Address (%lu) greater than maximum memory size",
+                       id, address);
                return 0;
-       } else
+       } else {
                return mem_infos[id].buf[address];
+       }
+}
+
+/* Read with a direct addressing mode at Address */
+unsigned char
+memory_read_direct(unsigned int address)
+{
+       if (address > 0xFF)
+               return memory_read8(EXT_MEM_ID, address);
+       else
+               return memory_read8(INT_MEM_ID, address);
+}
+
+/* Read with a indirect addressing mode at Address */
+unsigned char
+memory_read_indirect(unsigned int address)
+{
+       if (address > 0x7F)
+               return memory_read8(EXT_MEM_ID, address);
+       else
+               return memory_read8(INT_MEM_ID, address);
+}
+
+/* Read with a bit addressing mode at bit_address */
+unsigned char
+memory_read_bit(uint8_t bit_address)
+{
+       uint8_t byte_address;
+       uint8_t bit_number;
+       unsigned char bit_value;
+
+       memory_convert_bit_address(bit_address, &byte_address, &bit_number);
+
+       bit_value = (memory_read_direct(byte_address) >> bit_number);
+       bit_value &= 1;
+       return bit_value;
 }
 
 u_int8_t
@@ -199,45 +295,47 @@ pgm_read_addr16(uint16_t base)
 
 /* Dump memory */
 void
-DumpMem(char *Address, char *Asize, int memory_id)
+memory_dump(unsigned int address, int size, int memory_id)
 {
-       unsigned int MemAddress;
-       int size;
-       int Offset, Column;
+       int rc;
+       int offset, col;
 
-       if (strlen(Address) != 0) {
-               if (STREQ(Address, "PC"))
-                       MemAddress = cpu8051.pc;
-               else
-                       MemAddress = Ascii2Hex(Address, strlen(Address));
-       } else {
-               MemAddress = 0;
+       if (size == 0) {
+               log_err("invalid size: 0");
+               return;
        }
 
-       if (strlen(Asize) != 0) {
-               size = Ascii2Hex(Asize, strlen(Asize));
-       } else {
-               size = 256; /* Default size if not specified. */
+       /* Validate start address. */
+       rc = memory_check_address(memory_id, address, DISPLAY_ERROR_YES);
+       if (!rc) {
+               /* Validate end address. */
+               rc = memory_check_address(memory_id, address + (size - 1),
+                                         DISPLAY_ERROR_NO);
+               if (!rc)
+                       log_err("Trying to read beyond memory limit");
        }
 
-       for (Offset = 0; Offset < size; Offset += 16) {
+       if (!rc)
+               return;
+
+       for (offset = 0; offset < size; offset += 16) {
                unsigned char data[16];
 
-               printf("%.4X ", MemAddress + Offset);
+               printf("%.4X ", address + offset);
 
-               for (Column = 0; Column < 16; Column++) {
-                       data[Column] = memory_read8(memory_id, MemAddress +
-                                                   Offset + Column);
-                       printf(" %.2X", (int) data[Column]);
+               for (col = 0; col < 16; col++) {
+                       data[col] = memory_read8(memory_id, address +
+                                                offset + col);
+                       printf(" %.2X", (int) data[col]);
                }
                printf("  ");
 
                /* Display any ASCII characters */
-               for (Column = 0; Column < 16; Column++) {
-                       if ((int) data[Column] >= 32 &&
-                           (int) data[Column] <= 126) {
-                               printf("%c", data[Column]);
-                       else
+               for (col = 0; col < 16; col++) {
+                       if ((int) data[col] >= 32 &&
+                           (int) data[col] <= 126)
+                               printf("%c", data[col]);
+                       else
                                printf(".");
                }
                printf("\n");