Refactor code to read/write different memory types
authorHugo Villeneuve <hugo@hugovil.com>
Mon, 28 Oct 2013 02:48:24 +0000 (22:48 -0400)
committerHugo Villeneuve <hugo@hugovil.com>
Wed, 6 Nov 2013 02:50:18 +0000 (21:50 -0500)
Dynamic memory buffers allocation depending on sizes specified with command-line
options.

Add future support for separate IRAM and SFR buffers.

src/cpu8051.c
src/memory.c
src/memory.h
src/options.c
src/regwin.c

index b83175d..a44cd7f 100644 (file)
@@ -95,6 +95,8 @@ ToggleBreakpoint(unsigned int address)
 void
 cpu8051_init(void)
 {
+       memory_init();
+
        cpu8051.pc = 0;
        cpu8051.clock = 0;
        cpu8051.active_priority = -1;
@@ -105,24 +107,18 @@ cpu8051_init(void)
 void
 cpu8051_Reset(void)
 {
-       int i;
-
        cpu8051.pc = 0;
        cpu8051.clock = 0;
        cpu8051.active_priority = -1;
 
-       /* Reset registers */
-
-       for (i = 0; i < 256; i++) {
-               /* Clear  IRAM and SFR */
-               memory_write8(INT_MEM_ID, i, 0);
-       }
+       /* Clear IRAM and SFR. */
+       memory_clear(INT_MEM_ID);
 
-       memory_write8(INT_MEM_ID, _P0_, 0xFF);
-       memory_write8(INT_MEM_ID, _P1_, 0xFF);
-       memory_write8(INT_MEM_ID, _P2_, 0xFF);
-       memory_write8(INT_MEM_ID, _P3_, 0xFF);
-       memory_write8(INT_MEM_ID, _SP_, 0x07);
+       memory_sfr_write8(_P0_, 0xFF);
+       memory_sfr_write8(_P1_, 0xFF);
+       memory_sfr_write8(_P2_, 0xFF);
+       memory_sfr_write8(_P3_, 0xFF);
+       memory_sfr_write8(_SP_, 0x07);
 }
 
 static void
index c748cfe..fec85c1 100644 (file)
 #include "cpu8051.h"
 #include "hexfile.h"
 #include "memory.h"
+#include "options.h"
 
-static u_int8_t pgm_mem[PGM_MEM_MAX_SIZE];
-static u_int8_t int_mem[INT_MEM_MAX_SIZE];
-static u_int8_t ext_mem[EXT_MEM_MAX_SIZE];
+struct mem_infos_t {
+       int size;
+       int max_size;
+       u_int8_t *buf;
+};
+
+struct mem_infos_t mem_infos[MEM_ID_COUNT];
 
+extern struct options_t options;
+
+/* Init each 8051 memory sections. */
 void
-memory_write8(int memory_id, unsigned long address, u_int8_t value)
+memory_init(void)
 {
-       switch (memory_id) {
-       case PGM_MEM_ID:
-               if (address >= PGM_MEM_MAX_SIZE) {
-                       printf("Address (%lu) is greater than PGM_MEM_MAX_SIZE\n",
-                              address);
-                       return;
-               } else
-                       pgm_mem[address] = value;
-               break;
-       case INT_MEM_ID:
-               if (address >= INT_MEM_MAX_SIZE) {
-                       printf("Address (%lu) is greater than INT_MEM_MAX_SIZE\n",
-                              address);
-                       return;
-               } else
-                       int_mem[address] = value;
-               break;
-       case EXT_MEM_ID:
-               if (address >= EXT_MEM_MAX_SIZE) {
-                       printf("Address (%lu) is greater than EXT_MEM_MAX_SIZE\n",
-                              address);
-                       return;
-               } else
-                       ext_mem[address] = value;
-               break;
-       default:
-               /* Error. */
-               break;
+       int k;
+       struct mem_infos_t *m;
+
+       /* Set desired and maximum allowable sizes for each memory type. */
+       mem_infos[PGM_MEM_ID].size = options.pram_size;
+       mem_infos[PGM_MEM_ID].max_size = PGM_MEM_MAX_SIZE;
+
+       mem_infos[INT_MEM_ID].size = options.iram_size;
+       mem_infos[INT_MEM_ID].max_size = INT_MEM_MAX_SIZE;
+
+       mem_infos[EXT_MEM_ID].size = options.xram_size;
+       mem_infos[EXT_MEM_ID].max_size = EXT_MEM_MAX_SIZE;
+
+       /* Verify if desired sizes are valid, and if so allocate memory. */
+       for (k = 0; k < MEM_ID_COUNT; k++) {
+               m = &mem_infos[k];
+
+               if (m->size > m->max_size) {
+                       log_fail_no_exit("Memory size invalid (max = %d)",
+                                        m->max_size);
+                       exit(1);
+               }
+
+               m->buf = malloc(m->size);
+               if (m->buf == NULL) {
+                       log_fail_no_exit("%s", strerror(errno));
+                       exit(1);
+               }
        }
 }
 
+void
+memory_clear(enum mem_id_t id)
+{
+       memset(mem_infos[id].buf, 0, mem_infos[id].size);
+}
+
+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);
+               return;
+       } else
+               mem_infos[id].buf[address] = value;
+}
+
+void
+memory_sfr_write8(unsigned long address, u_int8_t value)
+{
+       /* SFR registers are from addresses $80 to $FF. */
+       memory_write8(INT_MEM_ID, address, value);
+}
+
 u_int8_t
-memory_read8(int memory_id, unsigned long address)
+memory_read8(enum mem_id_t id, unsigned long address)
 {
-       switch (memory_id) {
-       case PGM_MEM_ID:
-               if (address < PGM_MEM_MAX_SIZE)
-                       return pgm_mem[address];
-               else {
-                       printf("Address (%lu) is greater than PGM_MEM_MAX_SIZE\n",
-                               address);
-                       return 0;
-               }
-               break;
-       case INT_MEM_ID:
-               if (address < INT_MEM_MAX_SIZE)
-                       return int_mem[address];
-               else {
-                       printf("Address (%lu) is greater than INT_MEM_MAX_SIZE\n",
-                              address);
-                       return 0;
-               }
-               break;
-       case EXT_MEM_ID:
-               if (address < EXT_MEM_MAX_SIZE)
-                       return ext_mem[address];
-               else {
-                       printf("Address (%lu) is greater than EXT_MEM_MAX_SIZE\n",
-                              address);
-                       return 0;
-               }
-               break;
-       default:
-               /* Error. */
+       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);
                return 0;
-               break;
-       }
+       } else
+               return mem_infos[id].buf[address];
+}
+
+u_int8_t
+memory_sfr_read8(unsigned long address)
+{
+       /* SFR registers are from addresses $80 to $FF. */
+       return memory_read8(INT_MEM_ID, address);
 }
 
 /* Dump memory */
index d5e426d..9064813 100644 (file)
 #define INT_MEM_MAX_SIZE   256
 #define EXT_MEM_MAX_SIZE 65536
 
+#define PGM_MEM_DEFAULT_SIZE 8192
 #define EXT_MEM_DEFAULT_SIZE 1024
 
-enum {
-  PGM_MEM_ID,
-  INT_MEM_ID,
-  EXT_MEM_ID
+enum mem_id_t {
+       PGM_MEM_ID,
+       INT_MEM_ID,
+       EXT_MEM_ID,
+       MEM_ID_COUNT
 };
 
 void
-memory_write8(int memory_id, unsigned long address, u_int8_t value);
+memory_init(void);
+
+void
+memory_clear(enum mem_id_t id);
+
+void
+memory_write8(enum mem_id_t id, unsigned long address, u_int8_t value);
+
+void
+memory_sfr_write8(unsigned long address, u_int8_t value);
+
+u_int8_t
+memory_read8(enum mem_id_t id, unsigned long address);
 
 u_int8_t
-memory_read8(int memory_id, unsigned long address);
+memory_sfr_read8(unsigned long address);
 
 void
 DumpMem(char *Address, char *Asize, int memory_id);
index 3616f51..3c292d4 100644 (file)
@@ -83,29 +83,25 @@ static void
 decode_memory_size(char *arg, struct argp_state *state, int memid)
 {
        char *endptr;
-       int max_size;
        int *dest;
 
-       if (memid == INT_MEM_ID) {
-               max_size = INT_MEM_MAX_SIZE;
+       if (memid == INT_MEM_ID)
                dest = &options.iram_size;
-       } else {
-               max_size = EXT_MEM_MAX_SIZE;
+       else if (memid == EXT_MEM_ID)
                dest = &options.xram_size;
-       }
+       else
+               exit(1); /* Programming error. */
 
+       /*
+        * Sizes versus max memory sizes will be checked when calling
+        * memory_init().
+        */
        *dest = strtol(arg, &endptr, 0);
 
        if (*endptr != '\0') {
                log_fail_no_exit("Invalid memory size");
                argp_usage(state);
        }
-
-       if (*dest > max_size) {
-               log_fail_no_exit("Invalid maximum memory size (max = %d)",
-                       max_size);
-               argp_usage(state);
-       }
 }
 
 /* Parse a single option. */
index e549c96..e5708f2 100644 (file)
@@ -28,6 +28,7 @@
 #include "common.h"
 #include "reg8051.h"
 #include "cpu8051.h"
+#include "memory.h"
 #include "regwin.h"
 #include "memwin.h"
 #include "pgmwin.h"
@@ -62,11 +63,11 @@ static unsigned int
 regwin_read(int addr, int width)
 {
        if (width == 2)
-               return cpu8051_ReadD(addr);
+               return memory_sfr_read8(addr);
        else if (width == 4) {
                /* Address is low address. */
-               return (cpu8051_ReadD(addr + 1) << 8) |
-                       cpu8051_ReadD(addr);
+               return (memory_sfr_read8(addr + 1) << 8) |
+                       memory_sfr_read8(addr);
        } else
                return 0xFFFFFFFF;
 }
@@ -75,11 +76,11 @@ static void
 regwin_write(int addr, int val, int width)
 {
        if (width == 2)
-               cpu8051_WriteD(addr, (u_int8_t) val);
+               memory_sfr_write8(addr, (u_int8_t) val);
        else if (width == 4) {
                /* Address is low address. */
-               cpu8051_WriteD(addr + 1, (u_int8_t) ((val & 0x0000FFFF) >> 8));
-               cpu8051_WriteD(addr, (u_int8_t) val);
+               memory_sfr_write8(addr + 1, (u_int8_t) ((val & 0x0000FFFF) >> 8));
+               memory_sfr_write8(addr, (u_int8_t) val);
        }
 };
 
@@ -100,47 +101,54 @@ regwin_write_pc(int param, int val)
 static unsigned int
 regwin_read_timer(int timer_low_addr)
 {
-       return (cpu8051_ReadD(timer_low_addr + 2) << 8) |
-               cpu8051_ReadD(timer_low_addr);
+       return (memory_sfr_read8(timer_low_addr + 2) << 8) |
+               memory_sfr_read8(timer_low_addr);
 }
 
 static void
 regwin_write_timer(int timer_low_addr, int val)
 {
-       cpu8051_WriteD(timer_low_addr + 2, (u_int8_t) ((val & 0x0000FFFF) >> 8));
-       cpu8051_WriteD(timer_low_addr, (u_int8_t) val);
+       memory_sfr_write8(timer_low_addr + 2, (u_int8_t) ((val & 0x0000FFFF) >> 8));
+       memory_sfr_write8(timer_low_addr, (u_int8_t) val);
+}
+
+static u_int8_t
+regwin_read_bank_offset(void)
+{
+       return memory_sfr_read8(_PSW_) & 0x18;
 }
 
 static unsigned int
 regwin_read_bank(int dummy)
 {
-       return BANKPSW >> 3;
+       return regwin_read_bank_offset() >> 3;
 }
 
 static void
 regwin_write_bank(int param, int bank_number)
 {
-       u_int8_t psw = cpu8051_ReadD(_PSW_);
+       u_int8_t psw = memory_sfr_read8(_PSW_);
 
        if ((bank_number < 0) || (bank_number > 3)) {
                log_info("Error: invalid bank number: %d", bank_number);
                bank_number = 0;
        }
 
-       cpu8051_WriteD(_PSW_, (psw & ~0x18) | (bank_number << 3));
+       memory_sfr_write8(_PSW_, (psw & ~0x18) | (bank_number << 3));
 }
 
-/* Read R0 - R7 in current bank. */
+/* Indirect read of R0 - R7 in current bank from internal memory. */
 static unsigned int
 regwin_read_rx(int offset)
 {
-       return cpu8051_ReadD(BANKPSW + offset);
+       return memory_read8(INT_MEM_ID, regwin_read_bank_offset() + offset);
 }
 
+/* Indirect write to R0 - R7 in current bank to internal memory. */
 static void
 regwin_write_rx(int offset, int val)
 {
-       cpu8051_WriteD(BANKPSW + offset, (u_int8_t) val);
+       memory_write8(INT_MEM_ID, regwin_read_bank_offset() + offset, (u_int8_t) val);
 }
 
 /* This array defines how to read value for each register. */