Remove obsolescent macro AM_PROG_CC_C_O
[emu8051.git] / src / memory.c
index 0b69e32..c5b2acf 100644 (file)
 
 #include "common.h"
 #include "cpu8051.h"
+#include "reg8051.h"
 #include "hexfile.h"
 #include "memory.h"
+#include "options.h"
 
-#define PGM_MEM_SIZE 65536
-#define INT_MEM_SIZE 256 /* IRAM = Direct addresses $00 to $7F
-                         * SFR  = Direct addresses $80 to $FF */
-#define EXT_MEM_SIZE 65536
+struct mem_infos_t {
+       int size;
+       int max_size;
+       u_int8_t *buf;
+};
 
-static u_int8_t pgm_mem[PGM_MEM_SIZE];
-static u_int8_t int_mem[INT_MEM_SIZE];
-static u_int8_t ext_mem[EXT_MEM_SIZE];
+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_SIZE) {
-                       printf("Address (%lu) is greater than PGM_MEM_SIZE\n",
-                              address);
-                       return;
-               } else
-                       pgm_mem[address] = value;
-               break;
-       case INT_MEM_ID:
-               if (address >= INT_MEM_SIZE) {
-                       printf("Address (%lu) is greater than INT_MEM_SIZE\n",
-                              address);
-                       return;
-               } else
-                       int_mem[address] = value;
-               break;
-       case EXT_MEM_ID:
-               if (address >= EXT_MEM_SIZE) {
-                       printf("Address (%lu) is greater than EXT_MEM_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_err("Memory size invalid (max = %d)", m->max_size);
+                       exit(1);
+               }
+
+               m->buf = malloc(m->size);
+               if (m->buf == NULL) {
+                       log_err("%s", strerror(errno));
+                       exit(1);
+               }
+
+               memset(m->buf, 0x00, m->size);
        }
 }
 
+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);
+}
+
+void
+memory_sfr_write_dptr(u_int16_t value)
+{
+       memory_write8(INT_MEM_ID, _DPTRHIGH_, value >> 8);
+       memory_write8(INT_MEM_ID, _DPTRLOW_, (uint8_t) 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_SIZE)
-                       return pgm_mem[address];
-               else {
-                       printf("Address (%lu) is greater than PGM_MEM_SIZE\n",
-                               address);
-                       return 0;
-               }
-               break;
-       case INT_MEM_ID:
-               if (address < INT_MEM_SIZE)
-                       return int_mem[address];
-               else {
-                       printf("Address (%lu) is greater than INT_MEM_SIZE\n",
-                              address);
-                       return 0;
-               }
-               break;
-       case EXT_MEM_ID:
-               if (address < EXT_MEM_SIZE)
-                       return ext_mem[address];
-               else {
-                       printf("Address (%lu) is greater than EXT_MEM_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);
+}
+
+u_int16_t
+memory_sfr_read_dptr(void)
+{
+       return (memory_read8(INT_MEM_ID, _DPTRHIGH_) << 8) +
+               memory_read8(INT_MEM_ID, _DPTRLOW_);
+}
+
+void
+stack_push8(uint8_t value)
+{
+       uint8_t sp;
+
+       sp = memory_read8(INT_MEM_ID, _SP_);
+
+       memory_write8(INT_MEM_ID, ++sp, value);
+       memory_write8(INT_MEM_ID, _SP_, sp); /* Save new stack pointer */
+}
+
+void
+stack_push16(uint16_t value)
+{
+       uint8_t sp;
+
+       sp = memory_read8(INT_MEM_ID, _SP_);
+
+       memory_write8(INT_MEM_ID, ++sp, (uint8_t) value); /* Write LSB */
+       memory_write8(INT_MEM_ID, ++sp, value >> 8);      /* Write MSB */
+       memory_write8(INT_MEM_ID, _SP_, sp); /* Save new stack pointer */
+}
+
+uint8_t
+stack_pop8(void)
+{
+       uint8_t sp;
+       uint8_t value;
+
+       sp = memory_read8(INT_MEM_ID, _SP_);
+
+       value = memory_read8(INT_MEM_ID, sp--);
+       memory_write8(INT_MEM_ID, _SP_, sp); /* Save new stack pointer */
+
+       return value;
+}
+
+uint16_t
+stack_pop16(void)
+{
+       uint8_t sp;
+       uint16_t value;
+
+       sp = memory_read8(INT_MEM_ID, _SP_);
+
+       value = memory_read8(INT_MEM_ID, sp--) << 8; /* Read MSB */
+       value |= memory_read8(INT_MEM_ID, sp--);     /* Read LSB */
+       memory_write8(INT_MEM_ID, _SP_, sp); /* Save new stack pointer */
+
+       return value;
+}
+
+/* Read a 16-bit address from PGM memory, starting at <base> offset */
+uint16_t
+pgm_read_addr16(uint16_t base)
+{
+       uint16_t addr;
+
+       addr = memory_read8(PGM_MEM_ID, base) << 8; /* MSB */
+       addr |= memory_read8(PGM_MEM_ID, base + 1); /* LSB */
+
+       return addr;
 }
 
 /* Dump memory */
 void
-DumpMem(char *buf, char *Address, int memory_id)
+DumpMem(char *Address, char *Asize, int memory_id)
 {
        unsigned int MemAddress;
+       int size;
        int Offset, Column;
-       int size = 256;
-       int k = 0;
 
        if (strlen(Address) != 0) {
                if (STREQ(Address, "PC"))
@@ -126,33 +214,32 @@ DumpMem(char *buf, char *Address, int memory_id)
                MemAddress = 0;
        }
 
+       if (strlen(Asize) != 0) {
+               size = Ascii2Hex(Asize, strlen(Asize));
+       } else {
+               size = 256; /* Default size if not specified. */
+       }
+
        for (Offset = 0; Offset < size; Offset += 16) {
                unsigned char data[16];
 
-               sprintf(&buf[k], "%.4X ", MemAddress + Offset);
-               k = strlen(buf);
+               printf("%.4X ", MemAddress + Offset);
 
                for (Column = 0; Column < 16; Column++) {
                        data[Column] = memory_read8(memory_id, MemAddress +
                                                    Offset + Column);
-                       sprintf(&buf[k], " %.2X", (int) data[Column]);
-                       k = strlen(buf);
+                       printf(" %.2X", (int) data[Column]);
                }
-               sprintf(&buf[k], "  ");
-               k = strlen(buf);
+               printf("  ");
 
                /* Display any ASCII characters */
                for (Column = 0; Column < 16; Column++) {
                        if ((int) data[Column] >= 32 &&
                            (int) data[Column] <= 126) {
-                               sprintf(&buf[k], "%c", data[Column]);
-                               k = strlen(buf);
-                       } else {
-                               sprintf(&buf[k], ".");
-                               k = strlen(buf);
-                       }
+                               printf("%c", data[Column]);
+                       } else
+                               printf(".");
                }
-               sprintf(&buf[k], "\n");
-               k = strlen(buf);
+               printf("\n");
        }
 }