2002-10-12 Theodore A. Roth * src/avrcore.c: Add real simulation of rampz register. * src/avrcore.h: Ditto. * src/decoder.c: Ditto. * src/register.c: Ditto. * src/register.h: Ditto. Index: src/avrcore.c =================================================================== RCS file: /cvsroot/simulavr/simulavr/src/avrcore.c,v retrieving revision 1.57 diff -u -r1.57 avrcore.c --- src/avrcore.c 8 Oct 2002 16:46:40 -0000 1.57 +++ src/avrcore.c 13 Oct 2002 00:07:26 -0000 @@ -343,6 +343,7 @@ core->sreg = sreg_new(); core->flash = flash_new( flash_sz ); core->gpwr = gpwr_new(); + core->rampz = rampz_new(); core->mem = mem_new(); core->opcode_break_pt = 0xffff; @@ -374,6 +375,9 @@ avr_core_attach_vdev( core, (VDevice *)core->sreg ); class_ref( (AvrClass *)core->sreg ); + avr_core_attach_vdev( core, (VDevice *)core->rampz ); + class_ref( (AvrClass *)core->rampz ); + avr_core_attach_vdev( core, (VDevice *)core->gpwr ); class_ref( (AvrClass *)core->gpwr ); @@ -518,32 +522,59 @@ mem_write( core->mem, addr, val ); } -/** - * \brief Status Register Access Methods - */ +/** \name Status Register Access Methods */ + +/address@hidden/ + +/** \brief Get the value of the status register. */ + byte avr_core_sreg_get( AvrCore *core ) { return sreg_get( core->sreg ); } -/** \brief FIXME: write me. */ +/** \brief Set the value of the status register. */ + void avr_core_sreg_set( AvrCore *core, byte v ) { sreg_set( core->sreg, v ); } -/** \brief FIXME: write me. */ +/** \brief Get the value of bit \c b of the status register. */ + int avr_core_sreg_get_bit( AvrCore *core, int b ) { return sreg_get_bit( core->sreg, b ); } -/** \brief FIXME: write me. */ +/** \brief Set the value of bit \c b of the status register. */ + void avr_core_sreg_set_bit( AvrCore *core, int b, int v ) { sreg_set_bit( core->sreg, b, v ); } +/address@hidden/ + +/** \name RAMPZ access methods */ + +/address@hidden/ + +/** \brief Get the value of the rampz register. */ + +byte avr_core_rampz_get( AvrCore *core ) +{ + return rampz_get(core->rampz); +} + +/** \brief Set the value of the rampz register. */ + +void avr_core_rampz_set( AvrCore *core, byte v ) +{ + rampz_set(core->rampz, v); +} + +/address@hidden/ /** * \brief General Purpose Working Register Access Methods Index: src/avrcore.h =================================================================== RCS file: /cvsroot/simulavr/simulavr/src/avrcore.h,v retrieving revision 1.8 diff -u -r1.8 avrcore.h --- src/avrcore.h 8 Oct 2002 16:46:40 -0000 1.8 +++ src/avrcore.h 13 Oct 2002 00:07:26 -0000 @@ -83,7 +83,7 @@ */ byte RAMPX; /* Registers concatenated with the X, Y and Z registers */ byte RAMPY; /* enabling indirect addressing of the wholw data space */ - byte RAMPZ; /* on MCUs with more than 64K bytes date space, and constant */ + RAMPZ *rampz; /* on MCUs with more than 64K bytes date space, and constant */ /* data fetch on MCUs with more than 64K bytes profram space. */ byte RAMPD; /* Register concatenated with the Z register enabling direct */ @@ -141,6 +141,10 @@ extern void avr_core_sreg_set ( AvrCore *core, byte v ); extern int avr_core_sreg_get_bit( AvrCore *core, int b ); extern void avr_core_sreg_set_bit( AvrCore *core, int b, int val ); + +/* RAMPZ Access Methods */ +extern byte avr_core_rampz_get ( AvrCore *core ); +extern void avr_core_rampz_set ( AvrCore *core, byte v ); /* General Purpose Working Register Access Methods */ extern byte avr_core_gpwr_get ( AvrCore *core, int reg ); Index: src/decoder.c =================================================================== RCS file: /cvsroot/simulavr/simulavr/src/decoder.c,v retrieving revision 1.27 diff -u -r1.27 decoder.c --- src/decoder.c 16 Sep 2002 00:25:44 -0000 1.27 +++ src/decoder.c 13 Oct 2002 00:07:29 -0000 @@ -1053,7 +1053,7 @@ /* FIXME: Is this correct? */ /* Z is R31:R30 */ - Z = (((core->RAMPZ) & 0x3f) << 16) + + Z = ((avr_core_rampz_get(core) & 0x3f) << 16) + (avr_core_gpwr_get(core, 31) << 8) + avr_core_gpwr_get(core, 30); @@ -1098,7 +1098,7 @@ /* FIXME: Is this correct? */ /* Z is R31:R30 */ - Z = (((core->RAMPZ) & 0x3f) << 16) + + Z = ((avr_core_rampz_get(core) & 0x3f) << 16) + (avr_core_gpwr_get(core, 31) << 8) + avr_core_gpwr_get(core, 30); @@ -1117,7 +1117,7 @@ Z += 1; avr_core_gpwr_set( core, 30, Z & 0xff ); avr_core_gpwr_set( core, 31, Z >> 8 ); - core->RAMPZ = (Z >> 16) & 0x3f; + avr_core_rampz_set(core, (Z >> 16) & 0x3f); avr_core_PC_incr( core, 1 ); avr_core_inst_CKS_set( core, 3 ); Index: src/register.c =================================================================== RCS file: /cvsroot/simulavr/simulavr/src/register.c,v retrieving revision 1.28 diff -u -r1.28 register.c --- src/register.c 27 May 2002 18:01:40 -0000 1.28 +++ src/register.c 13 Oct 2002 00:07:29 -0000 @@ -572,3 +572,81 @@ return CB_RET_RETAIN; } +/****************************************************************************\ + * + * RAMPZ(VDevice) : The RAMPZ register used by ELPM and ESPM instructions. + * + * Even though the rampz register is not available to all devices, we will + * install it for all in the simulator. It just so much easier that way and + * we're already assuming that the compiler generated the correct code in + * many places anyways. Let's see if we get bit. + * +\****************************************************************************/ + +static byte rampz_read( VDevice *dev, int addr ); +static void rampz_write( VDevice *dev, int addr, byte val ); +static void rampz_reset( VDevice *dev ); +static char *rampz_reg_name( VDevice *dev, int addr ); + +RAMPZ *rampz_new( void ) +{ + RAMPZ *rampz; + + rampz = avr_new( RAMPZ, 1 ); + rampz_construct( rampz ); + class_overload_destroy( (AvrClass *)rampz, rampz_destroy ); + + return rampz; +} + +void rampz_construct( RAMPZ *rampz ) +{ + char *name = "RAMPZ"; + + if (rampz == NULL) + avr_error( "passed null ptr" ); + + vdev_construct( (VDevice *)rampz, name, RAMPZ_BASE, RAMPZ_SIZE, + rampz_read, rampz_write, rampz_reset, rampz_reg_name ); + + rampz->reg = 0; +} + +void rampz_destroy( void *rampz ) +{ + if (rampz == NULL) + return; + + vdev_destroy( rampz ); +} + +byte rampz_get( RAMPZ *rampz ) +{ + return rampz->reg; +} + +void rampz_set( RAMPZ *rampz, byte val ) +{ + rampz->reg = val; +} + +static byte rampz_read( VDevice *dev, int addr ) +{ + return rampz_get( (RAMPZ *)dev ); +} + +static void rampz_write( VDevice *dev, int addr, byte val ) +{ + rampz_set( (RAMPZ *)dev, val ); +} + +static void rampz_reset( VDevice *dev ) +{ + display_io_reg( RAMPZ_IO_REG, 0 ); + ((RAMPZ *)dev)->reg = 0; +} + +static char *rampz_reg_name( VDevice *dev, int addr ) +{ + return vdev_get_name( dev ); +} Index: src/register.h =================================================================== RCS file: /cvsroot/simulavr/simulavr/src/register.h,v retrieving revision 1.2 diff -u -r1.2 register.h --- src/register.h 18 Mar 2002 23:48:23 -0000 1.2 +++ src/register.h 13 Oct 2002 00:07:29 -0000 @@ -253,4 +253,30 @@ extern void wdtcr_update ( WDTCR *wdtcr ); +/****************************************************************************\ + * + * RAMPZ(VDevice) : The RAMPZ register used by ELPM and ESPM instructions. + * +\****************************************************************************/ + +enum _rampz_addr_info { + RAMPZ_BASE = 0x5b, /* base rampz mem addr */ + RAMPZ_SIZE = 0x01, + RAMPZ_IO_REG = RAMPZ_BASE - IO_REG_ADDR_BEGIN, +}; + +typedef struct _RAMPZ RAMPZ; + +struct _RAMPZ { + VDevice parent; + byte reg; +}; + +extern RAMPZ *rampz_new ( void ); +extern void rampz_construct ( RAMPZ *rampz ); +extern void rampz_destroy ( void *rampz ); + +extern byte rampz_get ( RAMPZ *rampz ); +extern void rampz_set ( RAMPZ *rampz, byte val ); + #endif /* SIM_REGISTER_H */