42 #include "avrmalloc.h" 64 static uint32_t hw_pop (Stack *stack,
int bytes);
65 static void hw_push (Stack *stack,
int bytes, uint32_t val);
67 static uint32_t mem_pop (Stack *stack,
int bytes);
68 static void mem_push (Stack *stack,
int bytes, uint32_t val);
135 return stack->pop (stack, bytes);
148 stack->push (stack, bytes, val);
184 stack->depth = depth;
185 stack->stack =
avr_new0 (uint32_t, depth);
196 avr_free (((HWStack *)stack)->stack);
203 hw_pop (Stack *stack,
int bytes)
205 HWStack *hwst = (HWStack *)stack;
207 uint32_t val = hwst->stack[0];
209 for (i = 0; i < (hwst->depth - 1); i++)
211 hwst->stack[i] = hwst->stack[i + 1];
220 hw_push (Stack *stack,
int bytes, uint32_t val)
222 HWStack *hwst = (HWStack *)stack;
225 for (i = (hwst->depth - 1); i; i--)
227 hwst->stack[i - 1] = hwst->stack[i];
230 hwst->stack[0] = val;
241 typedef struct _StackPointer StackPointer;
256 static StackPointer *sp_new (
int addr,
char *name);
257 static void sp_construct (StackPointer *sp,
int addr,
char *name);
258 static void sp_destroy (
void *sp);
259 static uint8_t sp_read (VDevice *dev,
int addr);
260 static void sp_write (VDevice *dev,
int addr, uint8_t val);
261 static void sp_reset (VDevice *dev);
262 static uint16_t sp_get (VDevice *sp);
263 static void sp_set (VDevice *sp, uint16_t val);
264 static void sp_add_addr (VDevice *vdev,
int addr,
char *name,
int rel_addr,
272 sp_create (
int addr,
char *name,
int rel_addr,
void *data)
274 return (VDevice *)sp_new (addr, name);
277 static StackPointer *
278 sp_new (
int addr,
char *name)
282 sp =
avr_new (StackPointer, 1);
283 sp_construct (sp, addr, name);
290 sp_construct (StackPointer *sp,
int addr,
char *name)
295 vdev_construct ((VDevice *)sp, sp_read, sp_write, sp_reset, sp_add_addr);
297 sp_add_addr ((VDevice *)sp, addr, name, 0, NULL);
299 sp_reset ((VDevice *)sp);
303 sp_destroy (
void *sp)
312 sp_read (VDevice *dev,
int addr)
314 StackPointer *sp = (StackPointer *)dev;
316 if (addr == sp->SPL_addr)
318 else if (addr == (sp->SPL_addr + 1))
327 sp_write (VDevice *dev,
int addr, uint8_t val)
332 StackPointer *sp = (StackPointer *)dev;
334 if (addr == sp->SPL_addr)
336 else if (addr == (sp->SPL_addr + 1))
343 sp_reset (VDevice *dev)
345 StackPointer *sp = (StackPointer *)dev;
354 return (((StackPointer *)sp)->SPH << 8) + ((StackPointer *)sp)->SPL;
358 sp_set (VDevice *sp, uint16_t val)
360 display_io_reg (SPL_IO_REG, ((StackPointer *)sp)->SPL = val & 0xff);
361 display_io_reg (SPH_IO_REG, ((StackPointer *)sp)->SPH = val >> 8);
365 sp_add_addr (VDevice *vdev,
int addr,
char *name,
int rel_addr,
void *data)
367 StackPointer *sp = (StackPointer *)vdev;
369 if (strncmp (
"SPL", name, 3) == 0)
372 else if (strncmp (
"SPH", name, 3) == 0)
413 if (stack->SP == NULL)
415 avr_error (
"attempt to attach non-extistant SPL register");
425 MemStack *_stack = (MemStack *)stack;
439 mem_pop (Stack *stack,
int bytes)
441 MemStack *mst = (MemStack *)stack;
444 uint16_t sp = sp_get (mst->SP);
446 if ((bytes < 0) || (bytes >=
sizeof (uint32_t)))
447 avr_error (
"bytes out of bounds: %d", bytes);
449 for (i = bytes - 1; i >= 0; i--)
452 val |= (
mem_read (mst->mem, sp) << (i * 8));
455 sp_set (mst->SP, sp);
463 mem_push (Stack *stack,
int bytes, uint32_t val)
465 MemStack *mst = (MemStack *)stack;
467 uint16_t sp = sp_get (mst->SP);
469 if ((bytes < 0) || (bytes >=
sizeof (uint32_t)))
470 avr_error (
"bytes out of bounds: %d", bytes);
472 for (i = 0; i < bytes; i++)
479 sp_set (mst->SP, sp);
void memstack_construct(MemStack *stack, Memory *mem, int spl_addr)
Constructor for MemStack object.
#define avr_new0(type, count)
Macro for allocating memory and initializing it to zero.
void hwstack_construct(HWStack *stack, int depth)
Constructor for HWStack object.
Stack * stack_new(StackFP_Pop pop, StackFP_Push push)
Allocates memory for a new Stack object.
void stack_destroy(void *stack)
Destructor for the Stack class.
void mem_write(Memory *mem, int addr, uint8_t val)
Writes byte to memory and updates display for io registers.
void vdev_destroy(void *dev)
Destructor for a VDevice.
void class_ref(AvrClass *klass)
Increments the reference count for the klass object.
HWStack * hwstack_new(int depth)
Allocate a new HWStack object.
VDevice * mem_get_vdevice_by_addr(Memory *mem, int addr)
Find the VDevice associated with the given address.
uint32_t stack_pop(Stack *stack, int bytes)
Pops a byte or a word off the stack and returns it.
void avr_free(void *ptr)
Free malloc'd memory.
void class_destroy(void *klass)
Releases resources allocated by class's <klass>_new() function.
uint8_t mem_read(Memory *mem, int addr)
Reads byte from memory and sanity-checks for valid address.
void stack_push(Stack *stack, int bytes, uint32_t val)
Pushes a byte or a word of data onto the stack.
void class_unref(AvrClass *klass)
Decrements the reference count for the klass object.
VDevice * sp_create(int addr, char *name, int rel_addr, void *data)
Create the Stack Pointer VDevice.
void vdev_construct(VDevice *dev, VDevFP_Read rd, VDevFP_Write wr, VDevFP_Reset reset, VDevFP_AddAddr add_addr)
Constructor for a VDevice.
#define avr_error(fmt, args...)
Print an error message to stderr and terminate program.
void memstack_destroy(void *stack)
Destructor for MemStack object.
void display_io_reg(int reg, uint8_t val)
Update an IO register in the display.
#define avr_new(type, count)
Macro for allocating memory.
void class_overload_destroy(AvrClass *klass, AvrClassFP_Destroy destroy)
Overload the default destroy method.
void hwstack_destroy(void *stack)
Destructor for HWStack object.
MemStack * memstack_new(Memory *mem, int spl_addr)
Allocate a new MemStack object.
void class_construct(AvrClass *klass)
Initializes the AvrClass data structure.
void stack_construct(Stack *stack, StackFP_Pop pop, StackFP_Push push)
Constructor for the Stack class.