X-Git-Url: http://gitweb.hugovil.com/?a=blobdiff_plain;f=src%2Fmemory.c;h=c5b2acf51c7384776af89fe6b60ad346e27bebcd;hb=8d9b71ab3848729da1cf90a38a599be0b08cbb5c;hp=202d8d334fe10d2519439d83a1acadfb33dac7a2;hpb=fb3b3529579773b8a14959cc6bc5bb2096fd0fe8;p=emu8051.git diff --git a/src/memory.c b/src/memory.c index 202d8d3..c5b2acf 100644 --- a/src/memory.c +++ b/src/memory.c @@ -24,101 +24,186 @@ #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 is greater than PGM_MEM_SIZE\n"); - return; - } - else { - pgm_mem[address] = value; - } - break; - case INT_MEM_ID: - if( address >= INT_MEM_SIZE) { - printf("Address is greater than INT_MEM_SIZE\n"); - return; - } - else { - int_mem[address] = value; - } - break; - case EXT_MEM_ID: - if( address >= EXT_MEM_SIZE ) { - printf("Address is greater than EXT_MEM_SIZE\n"); - return; + 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); } - else { - ext_mem[address] = value; + + m->buf = malloc(m->size); + if (m->buf == NULL) { + log_err("%s", strerror(errno)); + exit(1); } - break; - default: - /* Error. */ - break; + + 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 is greater than PGM_MEM_SIZE\n"); - return 0; - } - break; - case INT_MEM_ID: - if( address < INT_MEM_SIZE ) { - return int_mem[address]; - } - else { - printf("Address is greater than INT_MEM_SIZE\n"); - return 0; - } - break; - case EXT_MEM_ID: - if( address < EXT_MEM_SIZE ) { - return ext_mem[address]; - } - else { - printf("Address is greater than EXT_MEM_SIZE\n"); - 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 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")) @@ -129,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"); } }