|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object avrora.sim.BaseInterpreter
The BaseInterpreter
class represents a base class of the legacy interpreter and the generated
interpreter(s) that stores the state of the executing program, e.g. registers and flags, etc.
Nested Class Summary | |
protected class |
BaseInterpreter.ErrorReporter
The ErrorReporter class is used to report errors accessing segments. |
class |
BaseInterpreter.StateImpl
|
Field Summary | |
protected int |
bootPC
|
boolean |
C
|
protected MainClock |
clock
The clock field stores a reference to the main clock of the simulator. |
int |
cyclesConsumed
The cyclesConsumed field stores the number of cycles consumed in doing a part of the
simulation (e.g. executing an instruction or processing an interrupt). |
protected long |
delayCycles
The delayCycles field tracks the number of cycles that the microcontroller is delayed.
|
protected MulticastExceptionWatch |
exceptionWatch
The exceptionWatch stores a reference to a MulticastExceptionWatch
that contains all of the exception watches currently registered. |
protected CodeSegment |
flash
|
protected MulticastProbe |
globalProbe
The globalProbe field stores a reference to a MulticastProbe that contains
all of the probes to be fired before and after the main execution runLoop--i.e. before and after every
instruction. |
boolean |
H
|
boolean |
I
|
protected boolean |
innerLoop
The innerLoop field is a boolean that is used internally in the implementation of the
interpreter. |
protected int |
interruptBase
|
protected InterruptTable |
interrupts
|
protected ActiveRegister[] |
ioregs
|
boolean |
justReturnedFromInterrupt
The justReturnedFromInterrupt field is used internally in maintaining the invariant stated
in the hardware manual that at least one instruction following a return from an interrupt is executed
before another interrupt can be processed. |
boolean |
N
|
int |
nextPC
The nextPC field is used internally in maintaining the correct execution order of the
instructions. |
static int |
NUM_REGS
|
protected int |
pc
|
protected int |
RAMPZ
|
protected RegisterSet |
registers
|
boolean |
S
|
protected Instr[] |
shared_instr
|
protected boolean |
shouldRun
The shouldRun flag is used internally in the main execution runLoop to implement the
correct semantics of start() and stop() to the clients. |
protected Simulator |
simulator
The simulator field stores a reference to the simulator that this interpreter instance
corresponds to. |
protected boolean |
sleeping
The sleeping flag is used internally in the simulator when the microcontroller enters the
sleep mode. |
protected RWRegister |
SPH_reg
|
protected RWRegister |
SPL_reg
|
byte[] |
sram
|
protected int |
sram_max
|
protected int |
sram_start
|
protected MulticastWatch[] |
sram_watches
|
protected int |
SREG
|
static int |
SREG_C
|
static int |
SREG_H
|
static int |
SREG_I
|
static int |
SREG_N
|
protected ActiveRegister |
SREG_reg
|
static int |
SREG_S
|
static int |
SREG_T
|
static int |
SREG_V
|
static int |
SREG_Z
|
protected BaseInterpreter.StateImpl |
state
|
boolean |
T
|
boolean |
V
|
boolean |
Z
|
Constructor Summary | |
BaseInterpreter(Simulator simulator,
Program p,
MicrocontrollerProperties pr)
The constructor for the BaseInterpreter class initializes the node's flash,
SRAM, general purpose registers, IO registers, and loads the program onto the flash. |
Method Summary | |
protected void |
advanceClock(long delta)
The advanceClock() method advances the clock by the specified number of cycles. |
protected void |
commit()
The commit() method is used internally to commit the results of the instructiobn just executed.
|
protected void |
delay(long cycles)
The delay() method is used to add some delay cycles before the next instruction is executed.
|
void |
disableInterrupts()
The disableInterrupts() method disables all of the interrupts. |
void |
enableInterrupts()
The enableInterrupts() method enables all of the interrupts. |
byte |
getDataByte(int address)
The getDataByte() method reads a byte value from the data memory (SRAM) at the specified
address. |
Instr |
getInstr(int address)
The getInstr() can be used to retrieve a reference to the Instr object
representing the instruction at the specified program address. |
int |
getInstrSize(int npc)
The getInstrSize() method reads the size of the instruction at the given program address.
|
int |
getInterruptBase()
The getInterruptBase() method returns the base address of the interrupt table. |
InterruptTable |
getInterruptTable()
The getInterruptTable() method returns a reference to the interrupt table for this
interpreter. |
protected int |
getInterruptVectorAddress(int inum)
The getInterruptVectorAddress() method computes the location in memory to jump to for the
given interrupt number. |
ActiveRegister |
getIOReg(int ioreg)
The getIOReg() method is used to retrieve a reference to the actual IOReg
instance stored internally in the state. |
byte |
getIORegisterByte(int ioreg)
The getIORegisterByte() method reads the value of an IO register. |
MainClock |
getMainClock()
The getMainClock() method returns a reference to the main clock for this interpreter.
|
int |
getPC()
The getPC() retrieves the current program counter. |
byte |
getProgramByte(int address)
The getProgramByte() method reads a byte value from the program (Flash) memory. |
byte |
getRegisterByte(int reg)
|
byte |
getRegisterByte(Register reg)
Read a general purpose register's current value as a byte. |
int |
getRegisterUnsigned(int reg)
The getRegisterUnsigned() method reads a register's value (without sign extension) |
int |
getRegisterUnsigned(Register reg)
Read a general purpose register's current value as an integer, without any sign extension. |
int |
getRegisterWord(int reg)
Read a general purpose register pair as an unsigned word. |
int |
getRegisterWord(Register reg)
Read a general purpose register pair as an unsigned word. |
Simulator |
getSimulator()
The getSimulator() method gets a reference to the simulator which encapsulates this
interpreter. |
int |
getSP()
The getSP() method reads the current value of the stack pointer. |
byte |
getSREG()
The getSREG() method reads the value of the status register. |
protected void |
insertExceptionWatch(Simulator.ExceptionWatch watch)
The insertExceptionWatch() method registers an ExceptionWatch to listen for
exceptional conditions in the machine. |
protected void |
insertIORWatch(Simulator.IORWatch p,
int ioreg_num)
The insertIORWatch() method is used internally to insert a watch on an IO register. |
protected void |
insertProbe(Simulator.Probe p)
The insertProbe() method allows a probe to be inserted that is executed before and after
every instruction that is executed by the simulator |
protected void |
insertProbe(Simulator.Probe p,
int addr)
The insertProbe() method is used internally to insert a probe on a particular instruction. |
protected void |
insertWatch(Simulator.Watch p,
int data_addr)
The insertWatch() method is used internally to insert a watch on a particular memory location. |
void |
installIOReg(int ioreg,
ActiveRegister reg)
The installIOReg() method installs the specified IOReg object to the specified IO
register number. |
byte |
popByte()
The popByte() method pops a byte from the stack by reading from the address pointed to by
SP+1 and incrementing the stack pointer. |
void |
pushByte(byte val)
The pushByte() method pushes a byte onto the stack by writing to the memory address
pointed to by the stack pointer and decrementing the stack pointer. |
protected void |
removeIORWatch(Simulator.IORWatch p,
int ioreg_num)
The removeIORWatch() method is used internally to remove a watch on an IO register. |
void |
removeProbe(Simulator.Probe b)
The removeProbe() method removes a probe from the global probe table (the probes executed
before and after every instruction). |
protected void |
removeProbe(Simulator.Probe p,
int addr)
The removeProbe() method is used internally to remove a probe from a particular instruction. |
protected void |
removeWatch(Simulator.Watch p,
int data_addr)
The removeWatch() method is used internally to remove a watch from a particular memory location. |
protected abstract void |
runLoop()
|
void |
setBootPC(int npc)
This method sets the booting address of the interpreter. |
void |
setEnabled(int inum,
boolean enabled)
The setEnabled() method is used by external devices (and mask registers) to enable
and disable interrupts. |
void |
setInterruptBase(int npc)
The setInterruptBase() method sets the base of the interrupt table. |
void |
setPosted(int inum,
boolean post)
The setPosted() |
protected void |
setSP(int val)
The setSP() method updates the value of the stack pointer. |
protected void |
start()
|
abstract int |
step()
The step() method steps this node forward one instruction or one clock cycle. |
void |
stop()
The stop() method terminates the execution of the simulation. |
protected void |
storeProgramMemory()
The storeProgramMemory() method is called when the program executes the SPM instruction
which stores to the program memory. |
void |
writeDataByte(int address,
byte val)
The writeDataByte() method writes a value to the data memory (SRAM) of the state. |
void |
writeFlashByte(int address,
byte val)
The writeFlashByte() method updates the flash memory one byte at a time.
|
void |
writeIORegisterByte(int ioreg,
byte val)
The writeIORegisterByte() method writes a value to the specified IO register. |
void |
writeRegisterByte(int reg,
byte val)
The writeRegisterByte() method writes a value to a general purpose register. |
protected void |
writeRegisterByte(Register reg,
byte val)
The writeRegisterByte() method writes a value to a general purpose register. |
void |
writeRegisterWord(int reg,
int val)
The writeRegisterWord method writes a word value to a general purpose register pair. |
protected void |
writeRegisterWord(Register reg,
int val)
The writeRegisterWord method writes a word value to a general purpose register pair. |
protected void |
writeSREG(byte val)
The writeSREG() method writes the value of the status register. |
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Methods inherited from interface avrora.core.InstrVisitor |
visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit |
Field Detail |
public static final int NUM_REGS
public static final int SREG_I
public static final int SREG_T
public static final int SREG_H
public static final int SREG_S
public static final int SREG_V
public static final int SREG_N
public static final int SREG_Z
public static final int SREG_C
protected final int SREG
protected final int RAMPZ
protected int bootPC
protected int interruptBase
protected int pc
protected final ActiveRegister[] ioregs
public byte[] sram
protected MulticastWatch[] sram_watches
protected final int sram_start
protected final int sram_max
public boolean I
public boolean T
public boolean H
public boolean S
public boolean V
public boolean N
public boolean Z
public boolean C
protected ActiveRegister SREG_reg
protected RWRegister SPL_reg
protected RWRegister SPH_reg
protected final CodeSegment flash
protected Instr[] shared_instr
protected final InterruptTable interrupts
protected final RegisterSet registers
protected final BaseInterpreter.StateImpl state
protected final MulticastProbe globalProbe
globalProbe
field stores a reference to a MulticastProbe
that contains
all of the probes to be fired before and after the main execution runLoop--i.e. before and after every
instruction.
protected MulticastExceptionWatch exceptionWatch
exceptionWatch
stores a reference to a MulticastExceptionWatch
that contains all of the exception watches currently registered.
protected boolean innerLoop
innerLoop
field is a boolean that is used internally in the implementation of the
interpreter. When something in the simulation changes (e.g. an interrupt is posted), this field is set
to false, and the execution loop (e.g. an interpretation or sleep loop) is broken out of.
public int nextPC
nextPC
field is used internally in maintaining the correct execution order of the
instructions.
public int cyclesConsumed
cyclesConsumed
field stores the number of cycles consumed in doing a part of the
simulation (e.g. executing an instruction or processing an interrupt).
protected long delayCycles
delayCycles
field tracks the number of cycles that the microcontroller is delayed.
Delay is needed because some devices pause execution of the program for some number of cycles, and also
to implement random delay at the beginning of startup in multiple node scenarios to prevent artificial
cycle-level synchronization.
protected boolean shouldRun
shouldRun
flag is used internally in the main execution runLoop to implement the
correct semantics of start()
and stop()
to the clients.
protected boolean sleeping
sleeping
flag is used internally in the simulator when the microcontroller enters the
sleep mode.
public boolean justReturnedFromInterrupt
justReturnedFromInterrupt
field is used internally in maintaining the invariant stated
in the hardware manual that at least one instruction following a return from an interrupt is executed
before another interrupt can be processed.
protected final Simulator simulator
simulator
field stores a reference to the simulator that this interpreter instance
corresponds to. There should be a one-to-one mapping between instances of the Simulator
class and instances of the BaseInterpreter
class.
protected final MainClock clock
clock
field stores a reference to the main clock of the simulator. This is
the same instance shared between the Simulator
, Microcontroller
, and
any devices that are attached directly to the main clock or to a derived clock.
Constructor Detail |
public BaseInterpreter(Simulator simulator, Program p, MicrocontrollerProperties pr)
BaseInterpreter
class initializes the node's flash,
SRAM, general purpose registers, IO registers, and loads the program onto the flash. It
uses the MicrocontrollerProperties
instance to configure the interpreter
such as the size of flash, SRAM, and location of IO registers.
simulator
- the simulator instance for this interpreterp
- the program to load onto this interpreter instancepr
- the properties of the microcontroller being simulatedMethod Detail |
public Simulator getSimulator()
getSimulator()
method gets a reference to the simulator which encapsulates this
interpreter.
public MainClock getMainClock()
getMainClock()
method returns a reference to the main clock for this interpreter.
The main clock keeps track of time for this microcontroller and contains an event queue that allows
events to be inserted to be executed in the future.
public InterruptTable getInterruptTable()
getInterruptTable()
method returns a reference to the interrupt table for this
interpreter. The interrupt table contains the status information about what interrupts are posted,
enabled, disabled, etc.
protected void start()
public abstract int step()
step()
method steps this node forward one instruction or one clock cycle. The node may
execute an instruction, execute events, wake from sleep, take an interrupt, etc. In the case of multi-cycle
instructions, the node will execute until the end of the instruction. The number of cycles consumed is
returned by this method.
public void stop()
stop()
method terminates the execution of the simulation.
protected abstract void runLoop()
protected int getInterruptVectorAddress(int inum)
getInterruptVectorAddress()
method computes the location in memory to jump to for the
given interrupt number. On the Atmega128, the starting point is the beginning of memory and each
interrupt vector slot is 4 bytes. On older architectures, this is not the case, therefore this method
has to be implemented according to the specific device being simulated.
inum
- the interrupt number
public void setPosted(int inum, boolean post)
setPosted() method is used by external devices to post and unpost interrupts.
- Parameters:
inum
- the interrupt number to post or unpostpost
- true if the interrupt should be posted; false if the interrupt should be unposted
public void setEnabled(int inum, boolean enabled)
setEnabled()
method is used by external devices (and mask registers) to enable
and disable interrupts.
inum
- the interrupt number to enable or disableenabled
- true if the interrupt should be enabled; false if the interrupt should be disabledprotected void insertProbe(Simulator.Probe p, int addr)
insertProbe()
method is used internally to insert a probe on a particular instruction.
p
- the probe to insert on an instructionaddr
- the address of the instruction on which to insert the probeprotected void insertExceptionWatch(Simulator.ExceptionWatch watch)
insertExceptionWatch()
method registers an ExceptionWatch to listen for
exceptional conditions in the machine.
watch
- The ExceptionWatch
instance to add.protected void insertProbe(Simulator.Probe p)
insertProbe()
method allows a probe to be inserted that is executed before and after
every instruction that is executed by the simulator
p
- the probe to insertprotected void removeProbe(Simulator.Probe p, int addr)
removeProbe()
method is used internally to remove a probe from a particular instruction.
p
- the probe to remove from an instructionaddr
- the address of the instruction from which to remove the probepublic void removeProbe(Simulator.Probe b)
removeProbe()
method removes a probe from the global probe table (the probes executed
before and after every instruction). The comparison used is reference equality, not
.equals()
.
b
- the probe to removeprotected void insertWatch(Simulator.Watch p, int data_addr)
insertWatch()
method is used internally to insert a watch on a particular memory location.
p
- the watch to insert on a memory locationdata_addr
- the address of the memory location on which to insert the watchprotected void removeWatch(Simulator.Watch p, int data_addr)
removeWatch()
method is used internally to remove a watch from a particular memory location.
p
- the watch to remove from the memory locationdata_addr
- the address of the memory location from which to remove the watchprotected void insertIORWatch(Simulator.IORWatch p, int ioreg_num)
insertIORWatch()
method is used internally to insert a watch on an IO register.
p
- the watch to add to the IO registerioreg_num
- the number of the IO register for which to insert the watchprotected void removeIORWatch(Simulator.IORWatch p, int ioreg_num)
removeIORWatch()
method is used internally to remove a watch on an IO register.
p
- the watch to remove from the IO registerioreg_num
- the number of the IO register for which to remove the watchprotected void advanceClock(long delta)
advanceClock()
method advances the clock by the specified number of cycles. It SHOULD NOT
be used externally. It also clears the cyclesConsumed
variable that is used to track the
number of cycles consumed by a single instruction.
delta
- the number of cycles to advance the clockprotected void delay(long cycles)
delay()
method is used to add some delay cycles before the next instruction is executed.
This is necessary because some devices such as the EEPROM actually delay execution of instructions while
they are working
cycles
- the number of cycles to delay the executionprotected void storeProgramMemory()
storeProgramMemory()
method is called when the program executes the SPM instruction
which stores to the program memory.
public byte getRegisterByte(Register reg)
reg
- the register to read
public byte getRegisterByte(int reg)
public int getRegisterUnsigned(Register reg)
reg
- the register to read
public int getRegisterUnsigned(int reg)
getRegisterUnsigned()
method reads a register's value (without sign extension)
reg
- the index into the register file
public int getRegisterWord(Register reg)
reg
- the low register of the pair to read
public int getRegisterWord(int reg)
reg
- the low register of the pair to read
public byte getSREG()
getSREG()
method reads the value of the status register. The status register contains
the I, T, H, S, V, N, Z, and C flags, in order from highest-order to lowest-order.
public byte getDataByte(int address)
getDataByte()
method reads a byte value from the data memory (SRAM) at the specified
address.
address
- the byte address to read
java.lang.ArrayIndexOutOfBoundsException
- if the specified address is not the valid memory rangepublic int getInstrSize(int npc)
getInstrSize()
method reads the size of the instruction at the given program address.
This is needed in the interpreter to compute the target of a skip instruction (an instruction that
skips over the instruction following it).
npc
- the program address of the instruction
public byte getIORegisterByte(int ioreg)
getIORegisterByte()
method reads the value of an IO register. Invocation of this
method causes an invocatiobn of the .read()
method on the corresponding internal
IOReg
object, and its value returned.
ioreg
- the IO register number
public byte getProgramByte(int address)
getProgramByte()
method reads a byte value from the program (Flash) memory. The flash
memory generally stores read-only values and the instructions of the program. Care should be taken that
the program memory at the specified address does not contain an instruction. This is because, in
general, programs should not read instructions as data, and secondly, because no assembler is present
in Avrora and therefore the actual byte value of an instruction may not be known.
address
- the byte address at which to read
InterpreterError.AddressOutOfBoundsException
- if the specified address is not the valid program memory rangepublic ActiveRegister getIOReg(int ioreg)
getIOReg()
method is used to retrieve a reference to the actual IOReg
instance stored internally in the state. This is generally only used in the simulator and device
implementations, and clients should probably not call this memory directly.
ioreg
- the IO register number to retrieve
IOReg
instance of the specified IO registerprotected void writeRegisterByte(Register reg, byte val)
writeRegisterByte()
method writes a value to a general purpose register. This is a
destructive update and should only be called from the appropriate places in the simulator.
reg
- the register to write the value toval
- the value to write to the registerprotected void writeRegisterWord(Register reg, int val)
writeRegisterWord
method writes a word value to a general purpose register pair. This is
a destructive update and should only be called from the appropriate places in the simulator. The
specified register and the next register in numerical order are updated with the low-order and
high-order byte of the value passed, respectively. The specified register should be less than r31,
since r32 (the next register) does not exist.
reg
- the low register of the pair to writeval
- the word value to write to the register pairpublic void writeRegisterByte(int reg, byte val)
writeRegisterByte()
method writes a value to a general purpose register. This is a
destructive update and should only be called from the appropriate places in the simulator.
reg
- the register to write the value toval
- the value to write to the registerpublic void writeRegisterWord(int reg, int val)
writeRegisterWord
method writes a word value to a general purpose register pair. This is
a destructive update and should only be called from the appropriate places in the simulator. The
specified register and the next register in numerical order are updated with the low-order and
high-order byte of the value passed, respectively. The specified register should be less than r31,
since r32 (the next register) does not exist.
reg
- the low register of the pair to writeval
- the word value to write to the register pairprotected void writeSREG(byte val)
writeSREG()
method writes the value of the status register. This method should only be
called from the appropriate places in the simulator.
val
- public void writeDataByte(int address, byte val)
writeDataByte()
method writes a value to the data memory (SRAM) of the state. This is
generally meant for the simulator, related classes, and device implementations to use, but could also
be used by debuggers and other tools.
address
- the byte address at which to write the valueval
- the value to writepublic void writeFlashByte(int address, byte val)
writeFlashByte()
method updates the flash memory one byte at a time.
WARNING: this method should NOT BE CALLED UNLESS EXTREME CARE IS TAKEN. The program
cannot alter its own flash data except through the flash writing procedure supported
in ReprogrammableCodeSegment
. This method is only meant for updating
node ID's that are stored in flash. DO NOT USE during execution!
address
- the address of the byte in flashval
- the new value to write into the flashpublic void installIOReg(int ioreg, ActiveRegister reg)
installIOReg()
method installs the specified IOReg
object to the specified IO
register number. This method is generally only used in the simulator and in device implementations to
set up the state correctly during initialization.
ioreg
- the IO register numberreg
- the IOReg object to install
public void writeIORegisterByte(int ioreg, byte val)
writeIORegisterByte()
method writes a value to the specified IO register. This is
generally only used internally to the simulator and device implementations, and client interfaces
should probably not call this method.
ioreg
- the IO register number to which to write the valueval
- the value to write to the IO registerpublic byte popByte()
popByte()
method pops a byte from the stack by reading from the address pointed to by
SP+1 and incrementing the stack pointer. This method, like all of the other methods that change the
state, should probably only be used within the simulator. This method should not be called with an
empty stack, as it will cause an exception consistent with trying to read non-existent memory.
public void pushByte(byte val)
pushByte()
method pushes a byte onto the stack by writing to the memory address
pointed to by the stack pointer and decrementing the stack pointer. This method, like all of the other
methods that change the state, should probably only be used within the simulator.
val
- the value to push onto the stackprotected void setSP(int val)
setSP()
method updates the value of the stack pointer. Generally the stack pointer is
stored in two IO registers SPL
and SPH
. This method should generally only be
used within the simulator.
val
- public void setBootPC(int npc)
npc
- the new PC to boot this interpreter frompublic int getInterruptBase()
getInterruptBase()
method returns the base address of the interrupt table.
public void setInterruptBase(int npc)
setInterruptBase()
method sets the base of the interrupt table.
npc
- the new base of the interrupt tablepublic int getPC()
getPC()
retrieves the current program counter.
public Instr getInstr(int address)
getInstr()
can be used to retrieve a reference to the Instr
object
representing the instruction at the specified program address. Care should be taken that the address in
program memory specified does not contain data. This is because Avrora does have a functioning
disassembler and assumes that the Instr
objects for each instruction in the program are
known a priori.
address
- the byte address from which to read the instruction
Instr
object representing the instruction at that address in
the program; null if there is no instruction at the specified addresspublic int getSP()
getSP()
method reads the current value of the stack pointer. Since the stack pointer
is stored in two IO registers, this method will cause the invocation of the .read()
method
on each of the IOReg
objects that store these values.
public void enableInterrupts()
enableInterrupts()
method enables all of the interrupts.
public void disableInterrupts()
disableInterrupts()
method disables all of the interrupts.
protected void commit()
commit()
method is used internally to commit the results of the instructiobn just executed.
This should only be used internally.
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |