X-Git-Url: http://gitweb.hugovil.com/?a=blobdiff_plain;f=src%2Fcommon%2Fmemory.c;h=ec7542aba0b75519095f18540fa43ff2dd7c336d;hb=8bfc53036ae2e040287a92c8a9e8f84571a19080;hp=2e3721040b7c59dea76a0fe70a4acf22b9dce8c4;hpb=cc6633f78b5f497c347b656f0c854455871f5efb;p=emu8051.git diff --git a/src/common/memory.c b/src/common/memory.c index 2e37210..ec7542a 100644 --- a/src/common/memory.c +++ b/src/common/memory.c @@ -4,21 +4,10 @@ * 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 #include #include @@ -75,6 +64,35 @@ 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) +{ + 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 { + return true; + } +} + +void +memory_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) { @@ -95,8 +113,44 @@ memory_write8(enum mem_id_t id, unsigned long address, u_int8_t value) " 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_write_direct(unsigned int address, unsigned char value) +{ + memory_write8(INT_MEM_ID, address, value); +} + +/* Write with an indirect addressing mode at Address the new Value */ +void +memory_write_indirect(unsigned int address, unsigned char value) +{ + if (address > 0x7F) { + memory_write8(EXT_MEM_ID, address, value); + return; + } + + memory_write8(INT_MEM_ID, address, value); +} + +/* Write with a bit addressing mode at BitAddress the new Value */ +void +memory_write_bit(uint8_t bit_address, uint8_t value) +{ + uint8_t byte_address; + uint8_t bit_number; + unsigned char byte_val, byte_mask; + + memory_convert_bit_address(bit_address, &byte_address, &bit_number); + + byte_mask = ((1 << bit_number) ^ 0xFF); + byte_val = memory_read_direct(byte_address) & byte_mask; + byte_val += value << bit_number; + memory_write_direct(byte_address, byte_val); } void @@ -121,8 +175,44 @@ memory_read8(enum mem_id_t id, unsigned long address) " 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 +memory_read_direct(unsigned int address) +{ + if (address > 0xFF) + return memory_read8(EXT_MEM_ID, address); + else + return memory_read8(INT_MEM_ID, address); +} + +/* Read with a indirect addressing mode at Address */ +unsigned char +memory_read_indirect(unsigned int address) +{ + if (address > 0x7F) + return memory_read8(EXT_MEM_ID, address); + else + return memory_read8(INT_MEM_ID, address); +} + +/* Read with a bit addressing mode at bit_address */ +unsigned char +memory_read_bit(uint8_t bit_address) +{ + uint8_t byte_address; + uint8_t bit_number; + unsigned char bit_value; + + memory_convert_bit_address(bit_address, &byte_address, &bit_number); + + bit_value = (memory_read_direct(byte_address) >> bit_number); + bit_value &= 1; + return bit_value; } u_int8_t @@ -205,45 +295,47 @@ pgm_read_addr16(uint16_t base) /* Dump memory */ void -DumpMem(char *Address, char *Asize, int memory_id) +memory_dump(unsigned int address, int size, int memory_id) { - unsigned int MemAddress; - int size; - int Offset, Column; + int rc; + int offset, col; - if (strlen(Address) != 0) { - if (STREQ(Address, "PC")) - MemAddress = cpu8051.pc; - else - MemAddress = Ascii2Hex(Address, strlen(Address)); - } else { - MemAddress = 0; + if (size == 0) { + log_err("invalid size: 0"); + return; } - if (strlen(Asize) != 0) { - size = Ascii2Hex(Asize, strlen(Asize)); - } else { - size = 256; /* Default size if not specified. */ + /* Validate start address. */ + rc = memory_check_address(memory_id, address, DISPLAY_ERROR_YES); + if (!rc) { + /* Validate end address. */ + rc = memory_check_address(memory_id, address + (size - 1), + DISPLAY_ERROR_NO); + if (!rc) + log_err("Trying to read beyond memory limit"); } - for (Offset = 0; Offset < size; Offset += 16) { + if (!rc) + return; + + for (offset = 0; offset < size; offset += 16) { unsigned char data[16]; - printf("%.4X ", MemAddress + Offset); + printf("%.4X ", address + offset); - for (Column = 0; Column < 16; Column++) { - data[Column] = memory_read8(memory_id, MemAddress + - Offset + Column); - printf(" %.2X", (int) data[Column]); + for (col = 0; col < 16; col++) { + data[col] = memory_read8(memory_id, address + + offset + col); + printf(" %.2X", (int) 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", data[col]); + else printf("."); } printf("\n");