X-Git-Url: http://gitweb.hugovil.com/?a=blobdiff_plain;f=src%2Fcommon%2Fmemory.c;h=daaa1faba2e22884020fbeab7eeb5d3e6b66d97f;hb=121bcb38f29409f10de63a68d86620c4beb75c97;hp=a2a33a5a10a4dbdb25cfdda63a5623a18cc94c63;hpb=93c2708beede1eae6700f622279560ac2620290e;p=emu8051.git diff --git a/src/common/memory.c b/src/common/memory.c index a2a33a5..daaa1fa 100644 --- a/src/common/memory.c +++ b/src/common/memory.c @@ -4,19 +4,7 @@ * Copyright (C) 1999 Jonathan St-André * Copyright (C) 1999 Hugo Villeneuve * - * 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 @@ -33,7 +21,7 @@ struct mem_infos_t { int size; int max_size; - u_int8_t *buf; + uint8_t *buf; }; struct mem_infos_t mem_infos[MEM_ID_COUNT]; @@ -42,7 +30,7 @@ extern struct options_t options; /* Init each 8051 memory sections. */ void -memory_init(void) +mem_init(void) { int k; struct mem_infos_t *m; @@ -62,14 +50,12 @@ memory_init(void) m = &mem_infos[k]; if (m->size > m->max_size) { - log_err("Memory size invalid (max = %d)", m->max_size); - exit(1); + log_fail("Memory size invalid (max = %d)", m->max_size); } m->buf = malloc(m->size); if (m->buf == NULL) { - log_err("%s", strerror(errno)); - exit(1); + log_fail("%s", strerror(errno)); } memset(m->buf, 0x00, m->size); @@ -78,80 +64,167 @@ 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) +mem_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 + } else { return true; + } +} + +void +mem_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) +uint8_t * +mem_getbuf(enum mem_id_t id, unsigned long address) { return &mem_infos[id].buf[address]; } void -memory_clear(enum mem_id_t id) +mem_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) +mem_write8(enum mem_id_t id, unsigned long address, uint8_t value) { 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_sfr_write8(unsigned long address, u_int8_t value) +mem_write_direct(unsigned int address, unsigned char value) +{ + mem_write8(INT_MEM_ID, address, value); +} + +/* Write with an indirect addressing mode at Address the new Value */ +void +mem_write_indirect(unsigned int address, unsigned char value) +{ + if (address > 0x7F) { + mem_write8(EXT_MEM_ID, address, value); + return; + } + + mem_write8(INT_MEM_ID, address, value); +} + +/* Write with a bit addressing mode at BitAddress the new Value */ +void +mem_write_bit(uint8_t bit_address, uint8_t value) +{ + uint8_t byte_address; + uint8_t bit_number; + unsigned char byte_val, byte_mask; + + mem_convert_bit_address(bit_address, &byte_address, &bit_number); + + byte_mask = ((1 << bit_number) ^ 0xFF); + byte_val = mem_read_direct(byte_address) & byte_mask; + byte_val += value << bit_number; + mem_write_direct(byte_address, byte_val); +} + +void +mem_sfr_write8(unsigned long address, uint8_t value) { /* SFR registers are from addresses $80 to $FF. */ - memory_write8(INT_MEM_ID, address, value); + mem_write8(INT_MEM_ID, address, value); } void -memory_sfr_write_dptr(u_int16_t value) +mem_sfr_write_dptr(uint16_t value) { - memory_write8(INT_MEM_ID, _DPTRHIGH_, value >> 8); - memory_write8(INT_MEM_ID, _DPTRLOW_, (uint8_t) value); + mem_write8(INT_MEM_ID, _DPTRHIGH_, value >> 8); + mem_write8(INT_MEM_ID, _DPTRLOW_, (uint8_t) value); } -u_int8_t -memory_read8(enum mem_id_t id, unsigned long address) +uint8_t +mem_read8(enum mem_id_t id, unsigned long 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 +mem_read_direct(unsigned int address) +{ + if (address > 0xFF) + return mem_read8(EXT_MEM_ID, address); + else + return mem_read8(INT_MEM_ID, address); } -u_int8_t -memory_sfr_read8(unsigned long address) +/* Read with a indirect addressing mode at Address */ +unsigned char +mem_read_indirect(unsigned int address) +{ + if (address > 0x7F) + return mem_read8(EXT_MEM_ID, address); + else + return mem_read8(INT_MEM_ID, address); +} + +/* Read with a bit addressing mode at bit_address */ +unsigned char +mem_read_bit(uint8_t bit_address) +{ + uint8_t byte_address; + uint8_t bit_number; + unsigned char bit_value; + + mem_convert_bit_address(bit_address, &byte_address, &bit_number); + + bit_value = (mem_read_direct(byte_address) >> bit_number); + bit_value &= 1; + return bit_value; +} + +uint8_t +mem_sfr_read8(unsigned long address) { /* SFR registers are from addresses $80 to $FF. */ - return memory_read8(INT_MEM_ID, address); + return mem_read8(INT_MEM_ID, address); } -u_int16_t -memory_sfr_read_dptr(void) +uint16_t +mem_sfr_read_dptr(void) { - return (memory_read8(INT_MEM_ID, _DPTRHIGH_) << 8) + - memory_read8(INT_MEM_ID, _DPTRLOW_); + return (mem_read8(INT_MEM_ID, _DPTRHIGH_) << 8) + + mem_read8(INT_MEM_ID, _DPTRLOW_); } void @@ -159,10 +232,10 @@ stack_push8(uint8_t value) { uint8_t sp; - sp = memory_read8(INT_MEM_ID, _SP_); + sp = mem_read8(INT_MEM_ID, _SP_); - memory_write8(INT_MEM_ID, ++sp, value); - memory_write8(INT_MEM_ID, _SP_, sp); /* Save new stack pointer */ + mem_write8(INT_MEM_ID, ++sp, value); + mem_write8(INT_MEM_ID, _SP_, sp); /* Save new stack pointer */ } void @@ -170,11 +243,11 @@ stack_push16(uint16_t value) { uint8_t sp; - sp = memory_read8(INT_MEM_ID, _SP_); + sp = mem_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 */ + mem_write8(INT_MEM_ID, ++sp, (uint8_t) value); /* Write LSB */ + mem_write8(INT_MEM_ID, ++sp, value >> 8); /* Write MSB */ + mem_write8(INT_MEM_ID, _SP_, sp); /* Save new stack pointer */ } uint8_t @@ -183,10 +256,10 @@ stack_pop8(void) uint8_t sp; uint8_t value; - sp = memory_read8(INT_MEM_ID, _SP_); + sp = mem_read8(INT_MEM_ID, _SP_); - value = memory_read8(INT_MEM_ID, sp--); - memory_write8(INT_MEM_ID, _SP_, sp); /* Save new stack pointer */ + value = mem_read8(INT_MEM_ID, sp--); + mem_write8(INT_MEM_ID, _SP_, sp); /* Save new stack pointer */ return value; } @@ -197,11 +270,11 @@ stack_pop16(void) uint8_t sp; uint16_t value; - sp = memory_read8(INT_MEM_ID, _SP_); + sp = mem_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 */ + value = mem_read8(INT_MEM_ID, sp--) << 8; /* Read MSB */ + value |= mem_read8(INT_MEM_ID, sp--); /* Read LSB */ + mem_write8(INT_MEM_ID, _SP_, sp); /* Save new stack pointer */ return value; } @@ -212,18 +285,18 @@ 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 */ + addr = mem_read8(PGM_MEM_ID, base) << 8; /* MSB */ + addr |= mem_read8(PGM_MEM_ID, base + 1); /* LSB */ return addr; } /* Dump memory */ void -memory_dump(unsigned int address, int size, int memory_id) +mem_dump(unsigned int address, int size, enum mem_id_t id) { int rc; - int Offset, Column; + int offset, col; if (size == 0) { log_err("invalid size: 0"); @@ -231,36 +304,35 @@ memory_dump(unsigned int address, int size, int memory_id) } /* Validate start address. */ - rc = memory_check_address(memory_id, address, DISPLAY_ERROR_YES); - if (rc != false) { + rc = mem_check_address(id, address, DISPLAY_ERROR_YES); + if (!rc) { /* Validate end address. */ - rc = memory_check_address(memory_id, address + (size - 1), - DISPLAY_ERROR_NO); - if (rc == false) + rc = mem_check_address(id, address + (size - 1), + DISPLAY_ERROR_NO); + if (!rc) log_err("Trying to read beyond memory limit"); } - if (rc == false) + if (!rc) return; - for (Offset = 0; Offset < size; Offset += 16) { - unsigned char data[16]; + for (offset = 0; offset < size; offset += 16) { + uint8_t data[16]; - printf("%.4X ", address + Offset); + printf("%.4X ", address + offset); - for (Column = 0; Column < 16; Column++) { - data[Column] = memory_read8(memory_id, address + - Offset + Column); - printf(" %.2X", (int) data[Column]); + for (col = 0; col < 16; col++) { + data[col] = mem_read8(id, address + offset + col); + printf(" %.2X", 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", (char) data[col]); + else printf("."); } printf("\n");