From e75510dd872ed3e50e6ddfcab328dab69f949177 Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Sun, 24 Nov 2013 14:39:18 -0500 Subject: [PATCH] Move SFR read/write functions to new file sfr.c --- src/Makefile.am | 1 + src/regwin.c | 325 +++------------------------------------------ src/sfr.c | 342 ++++++++++++++++++++++++++++++++++++++++++++++++ src/sfr.h | 46 +++++++ 4 files changed, 406 insertions(+), 308 deletions(-) create mode 100644 src/sfr.c create mode 100644 src/sfr.h diff --git a/src/Makefile.am b/src/Makefile.am index 5b5b25b..b5b4fbb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -26,6 +26,7 @@ common_SOURCES = \ memory.c \ memory.h \ psw.c psw.h \ + sfr.c sfr.h \ common.h \ reg8051.h diff --git a/src/regwin.c b/src/regwin.c index e784580..8c4cd4d 100644 --- a/src/regwin.c +++ b/src/regwin.c @@ -1,5 +1,5 @@ /* - * regwin.cpp + * regwin.c * * Copyright (C) 1999 Jonathan St-André * Copyright (C) 1999 Hugo Villeneuve @@ -28,6 +28,7 @@ #include "common.h" #include "reg8051.h" #include "cpu8051.h" +#include "sfr.h" #include "memory.h" #include "regwin.h" #include "memwin.h" @@ -39,7 +40,7 @@ static GtkWidget *reglist; #define LIST_VIEW_NAME "Registers" -#define DATA_ROWS 25 +#define DATA_ROWS SFR_REGS enum { @@ -48,265 +49,6 @@ enum N_COLUMNS, }; -#define HEX_DIGITS_2 2 -#define HEX_DIGITS_4 4 - -struct regwin_infos_t { - char *name; /* Register name */ - int w; /* Number of hex digits to display */ - unsigned int (*read_func)(int addr); /* Function to read value */ - void (*write_func)(int param, int val); /* Function to write value */ - int param; /* Optional parameter to pass to read function. */ -}; - -/* Generic read/write functions */ -static unsigned int -regwin_read(int addr, int width) -{ - if (width == 2) - return memory_sfr_read8(addr); - else if (width == 4) { - /* Address is low address. */ - return (memory_sfr_read8(addr + 1) << 8) | - memory_sfr_read8(addr); - } else - return 0xFFFFFFFF; -} - -static void -regwin_write(int addr, int val, int width) -{ - if (width == 2) - memory_sfr_write8(addr, (u_int8_t) val); - else if (width == 4) { - /* Address is low address. */ - memory_sfr_write8(addr + 1, (u_int8_t) ((val & 0x0000FFFF) >> 8)); - memory_sfr_write8(addr, (u_int8_t) val); - } -}; - -/* Specific read/write functions for special registers. */ - -static unsigned int -regwin_read_pc(int dummy) -{ - return cpu8051.pc; -} - -static void -regwin_write_pc(int param, int val) -{ - cpu8051.pc = (u_int16_t) val; -} - -static unsigned int -regwin_read_timer(int 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) -{ - 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 regwin_read_bank_offset() >> 3; -} - -static void -regwin_write_bank(int param, int bank_number) -{ - 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; - } - - memory_sfr_write8(_PSW_, (psw & ~0x18) | (bank_number << 3)); -} - -/* Indirect read of R0 - R7 in current bank from internal memory. */ -static unsigned int -regwin_read_rx(int 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) -{ - memory_write8(INT_MEM_ID, regwin_read_bank_offset() + offset, (u_int8_t) val); -} - -/* This array defines how to read value for each register. */ -static struct regwin_infos_t regwin_infos[DATA_ROWS] = { - { - "PC", - HEX_DIGITS_4, - regwin_read_pc, regwin_write_pc, - 0, /* Dummy */ - }, - { - "SP", - HEX_DIGITS_2, - NULL, NULL, - _SP_, - }, - { - "A", - HEX_DIGITS_2, - NULL, NULL, - _ACC_, - }, - { - "B", - HEX_DIGITS_2, - NULL, NULL, - _B_, - }, - { - "DPTR", - HEX_DIGITS_4, - NULL, NULL, - _DPL_, - }, - { - "P0", - HEX_DIGITS_2, - NULL, NULL, - _P0_, - }, - { - "P1", - HEX_DIGITS_2, - NULL, NULL, - _P1_, - }, - { - "P2", - HEX_DIGITS_2, - NULL, NULL, - _P2_, - }, - { - "P3", - HEX_DIGITS_2, - NULL, NULL, - _P3_, - }, - { - "TCON", - HEX_DIGITS_2, - NULL, NULL, - _TCON_, - }, - { - "TMOD", - HEX_DIGITS_2, - NULL, NULL, - _TMOD_, - }, - { - "TIMER0", - HEX_DIGITS_4, - regwin_read_timer, regwin_write_timer, - _TL0_, - }, - { - "TIMER1", - HEX_DIGITS_4, - regwin_read_timer, regwin_write_timer, - _TL1_, - }, - { - "SCON", - HEX_DIGITS_2, - NULL, NULL, - _SCON_, - }, - { - "IE", - HEX_DIGITS_2, - NULL, NULL, - _IE_, - }, - { - "IP", - HEX_DIGITS_2, - NULL, NULL, - _IP_, - }, - { - "BANK", - HEX_DIGITS_2, - regwin_read_bank, regwin_write_bank, - 0, /* Dummy */ - }, - /* R0-R7 Registers in current Bank */ - { - "R0", - HEX_DIGITS_2, - regwin_read_rx, regwin_write_rx, - _R0_, - }, - { - "R1", - HEX_DIGITS_2, - regwin_read_rx, regwin_write_rx, - _R1_, - }, - { - "R2", - HEX_DIGITS_2, - regwin_read_rx, regwin_write_rx, - _R2_, - }, - { - "R3", - HEX_DIGITS_2, - regwin_read_rx, regwin_write_rx, - _R3_, - }, - { - "R4", - HEX_DIGITS_2, - regwin_read_rx, regwin_write_rx, - _R4_, - }, - { - "R5", - HEX_DIGITS_2, - regwin_read_rx, regwin_write_rx, - _R5_, - }, - { - "R6", - HEX_DIGITS_2, - regwin_read_rx, regwin_write_rx, - _R6_, - }, - { - "R7", - HEX_DIGITS_2, - regwin_read_rx, regwin_write_rx, - _R7_, - }, -}; - /* Creating a model */ static GtkListStore * regwin_init_store(void) @@ -330,19 +72,6 @@ regwin_init_store(void) return store; } -static int -regwin_find_row(const char *regname) -{ - int row; - - for (row = 0; row < DATA_ROWS; row++) { - if (strcmp(regwin_infos[row].name, regname) == 0) - return row; - } - - return -1; /* Programming error. */ -} - static void regwin_cell_edited(GtkCellRendererText *cell, gchar *path_string, gchar *new_str, gpointer model) @@ -351,7 +80,7 @@ regwin_cell_edited(GtkCellRendererText *cell, gchar *path_string, int old; int new; char *str; - int row; + struct regwin_infos_t *regwin_infos; if (!model) { g_error("Unable to get model from cell renderer"); @@ -364,29 +93,28 @@ regwin_cell_edited(GtkCellRendererText *cell, gchar *path_string, gtk_tree_model_get(model, &iter, COL_NAME, &str, -1); log_info("Register: %s", str); - row = regwin_find_row(str); - log_info(" row = %d", row); + regwin_infos = sfr_get_infos(str); /* Read current (old) value. */ gtk_tree_model_get(model, &iter, COL_VAL, &str, -1); old = asciihex2int(str); - if (regwin_infos[row].w == 2) + if (regwin_infos->w == 2) log_info(" old value: $%02X", old); - else if (regwin_infos[row].w == 4) + else if (regwin_infos->w == 4) log_info(" old value: $%04X", old); new = asciihex2int(new_str); - if (regwin_infos[row].w == 2) { + if (regwin_infos->w == 2) { if ((new < 0) || (new > 0xFF)) { log_info(" new value: out of range"); new = old; /* Put back old value... */ } else { log_info(" new value: $%02X", new); } - } else if (regwin_infos[row].w == 4) { + } else if (regwin_infos->w == 4) { if ((new < 0) || (new > 0xFFFF)) { log_info(" new value: out of range"); new = old; /* Put back old value... */ @@ -395,22 +123,11 @@ regwin_cell_edited(GtkCellRendererText *cell, gchar *path_string, } } - /* Convert new value to text. */ - int2asciihex(new, str, regwin_infos[row].w); - /* Store new value in emulator register. */ - if (regwin_infos[row].write_func == NULL) { - /* - * Write register value using generic 8 or 16 bits write - * function, depending on width. - */ - regwin_write(regwin_infos[row].param, new, regwin_infos[row].w); - } else { - /* Write register value using custom function pointer. */ - regwin_infos[row].write_func(regwin_infos[row].param, new); - } + regwin_write(regwin_infos, new); /* Store new value in gtk model. */ + int2asciihex(new, str, regwin_infos->w); gtk_list_store_set(GTK_LIST_STORE(model), &iter, COL_VAL, str, -1); /* @@ -507,6 +224,7 @@ regwin_refresh(void) GtkTreeIter iter; int val; char str[8]; + struct regwin_infos_t *regwin_infos; if (row == 0) { /* Get first row in list store */ @@ -523,24 +241,15 @@ regwin_refresh(void) return; } - if (regwin_infos[row].read_func == NULL) { - /* - * Read register value using generic 8 or 16 bits read - * function, depending on width. - */ - val = regwin_read(regwin_infos[row].param, - regwin_infos[row].w); - } else { - /* Read register value using custom function pointer. */ - val = regwin_infos[row].read_func( - regwin_infos[row].param); - } + regwin_infos = sfr_get_infos_from_row(row); + + val = regwin_read(row); /* Convert to specified number of hex digits. */ - int2asciihex(val, str, regwin_infos[row].w); + int2asciihex(val, str, regwin_infos->w); gtk_list_store_set(store, &iter, - COL_NAME, regwin_infos[row].name, + COL_NAME, regwin_infos->name, COL_VAL, str, -1); } diff --git a/src/sfr.c b/src/sfr.c new file mode 100644 index 0000000..4b890b3 --- /dev/null +++ b/src/sfr.c @@ -0,0 +1,342 @@ +/* + * sfr.c + * + * Copyright (C) 2013 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "common.h" +#include "reg8051.h" +#include "cpu8051.h" +#include "sfr.h" +#include "memory.h" +#include "regwin.h" +#include "memwin.h" +#include "pgmwin.h" +#include "instructions_8051.h" + +#define HEX_DIGITS_2 2 +#define HEX_DIGITS_4 4 + +/* Specific read/write functions for special registers. */ + +static unsigned int +regwin_read_pc(int dummy) +{ + return cpu8051.pc; +} + +static void +regwin_write_pc(int param, int val) +{ + cpu8051.pc = (u_int16_t) val; +} + +static unsigned int +regwin_read_timer(int 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) +{ + 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 regwin_read_bank_offset() >> 3; +} + +static void +regwin_write_bank(int param, int bank_number) +{ + 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; + } + + memory_sfr_write8(_PSW_, (psw & ~0x18) | (bank_number << 3)); +} + +/* Indirect read of R0 - R7 in current bank from internal memory. */ +static unsigned int +regwin_read_rx(int 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) +{ + memory_write8(INT_MEM_ID, regwin_read_bank_offset() + offset, (u_int8_t) val); +} + +/* This array defines how to read value for each register. */ +static struct regwin_infos_t regwin_infos[SFR_REGS] = { + { + "PC", + HEX_DIGITS_4, + regwin_read_pc, regwin_write_pc, + 0, /* Dummy */ + }, + { + "SP", + HEX_DIGITS_2, + NULL, NULL, + _SP_, + }, + { + "A", + HEX_DIGITS_2, + NULL, NULL, + _ACC_, + }, + { + "B", + HEX_DIGITS_2, + NULL, NULL, + _B_, + }, + { + "DPTR", + HEX_DIGITS_4, + NULL, NULL, + _DPL_, + }, + { + "P0", + HEX_DIGITS_2, + NULL, NULL, + _P0_, + }, + { + "P1", + HEX_DIGITS_2, + NULL, NULL, + _P1_, + }, + { + "P2", + HEX_DIGITS_2, + NULL, NULL, + _P2_, + }, + { + "P3", + HEX_DIGITS_2, + NULL, NULL, + _P3_, + }, + { + "TCON", + HEX_DIGITS_2, + NULL, NULL, + _TCON_, + }, + { + "TMOD", + HEX_DIGITS_2, + NULL, NULL, + _TMOD_, + }, + { + "TIMER0", + HEX_DIGITS_4, + regwin_read_timer, regwin_write_timer, + _TL0_, + }, + { + "TIMER1", + HEX_DIGITS_4, + regwin_read_timer, regwin_write_timer, + _TL1_, + }, + { + "SCON", + HEX_DIGITS_2, + NULL, NULL, + _SCON_, + }, + { + "IE", + HEX_DIGITS_2, + NULL, NULL, + _IE_, + }, + { + "IP", + HEX_DIGITS_2, + NULL, NULL, + _IP_, + }, + { + "BANK", + HEX_DIGITS_2, + regwin_read_bank, regwin_write_bank, + 0, /* Dummy */ + }, + /* R0-R7 Registers in current Bank */ + { + "R0", + HEX_DIGITS_2, + regwin_read_rx, regwin_write_rx, + _R0_, + }, + { + "R1", + HEX_DIGITS_2, + regwin_read_rx, regwin_write_rx, + _R1_, + }, + { + "R2", + HEX_DIGITS_2, + regwin_read_rx, regwin_write_rx, + _R2_, + }, + { + "R3", + HEX_DIGITS_2, + regwin_read_rx, regwin_write_rx, + _R3_, + }, + { + "R4", + HEX_DIGITS_2, + regwin_read_rx, regwin_write_rx, + _R4_, + }, + { + "R5", + HEX_DIGITS_2, + regwin_read_rx, regwin_write_rx, + _R5_, + }, + { + "R6", + HEX_DIGITS_2, + regwin_read_rx, regwin_write_rx, + _R6_, + }, + { + "R7", + HEX_DIGITS_2, + regwin_read_rx, regwin_write_rx, + _R7_, + }, +}; + +/* Generic read/write functions */ +static unsigned int +regwin_read_generic(int addr, int width) +{ + if (width == 2) + return memory_sfr_read8(addr); + else if (width == 4) { + /* Address is low address. */ + return (memory_sfr_read8(addr + 1) << 8) | + memory_sfr_read8(addr); + } else + return 0xFFFFFFFF; +} + +static void +regwin_write_generic(int addr, int val, int width) +{ + if (width == 2) + memory_sfr_write8(addr, (u_int8_t) val); + else if (width == 4) { + /* Address is low address. */ + memory_sfr_write8(addr + 1, (u_int8_t) ((val & 0x0000FFFF) >> 8)); + memory_sfr_write8(addr, (u_int8_t) val); + } +}; + +int +regwin_read(int row) +{ + int val; + + if (regwin_infos[row].read_func == NULL) { + /* + * Read register value using generic 8 or 16 bits read + * function, depending on width. + */ + val = regwin_read_generic(regwin_infos[row].param, + regwin_infos[row].w); + } else { + /* Read register value using custom function pointer. */ + val = regwin_infos[row].read_func( + regwin_infos[row].param); + } + + return val; +} + +void +regwin_write(struct regwin_infos_t *p, int new) +{ + if (p->write_func == NULL) { + /* + * Write register value using generic 8 or 16 bits write + * function, depending on width. + */ + regwin_write_generic(p->param, new, p->w); + } else { + /* Write register value using custom function pointer. */ + p->write_func(p->param, new); + } +} + +struct regwin_infos_t * +sfr_get_infos(const char *regname) +{ + int row; + + for (row = 0; row < SFR_REGS; row++) { + if (strcmp(regwin_infos[row].name, regname) == 0) + return ®win_infos[row]; + } + + return NULL; /* Programming error. */ +} + +struct regwin_infos_t * +sfr_get_infos_from_row(int row) +{ + return ®win_infos[row]; +} + diff --git a/src/sfr.h b/src/sfr.h new file mode 100644 index 0000000..857af97 --- /dev/null +++ b/src/sfr.h @@ -0,0 +1,46 @@ +/* + * sfr.h + * + * Copyright (C) 2013 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. + */ + +#ifndef SFR_H +#define SFR_H 1 + +#define SFR_REGS 25 + +struct regwin_infos_t { + char *name; /* Register name */ + int w; /* Number of hex digits to display */ + unsigned int (*read_func)(int addr); /* Function to read value */ + void (*write_func)(int param, int val); /* Function to write value */ + int param; /* Optional parameter to pass to read function. */ +}; + +int +regwin_read(int row); + +void +regwin_write(struct regwin_infos_t *p, int new); + +struct regwin_infos_t * +sfr_get_infos(const char *regname); + +struct regwin_infos_t * +sfr_get_infos_from_row(int row); + +#endif /* SFR_H */ -- 2.20.1