Dynamic memory buffers allocation depending on sizes specified with command-line
options.
Add future support for separate IRAM and SFR buffers.
void
cpu8051_init(void)
{
+ memory_init();
+
cpu8051.pc = 0;
cpu8051.clock = 0;
cpu8051.active_priority = -1;
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
#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 */
#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);
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. */
#include "common.h"
#include "reg8051.h"
#include "cpu8051.h"
+#include "memory.h"
#include "regwin.h"
#include "memwin.h"
#include "pgmwin.h"
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;
}
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);
}
};
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. */