00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
#include <config.h>
00036
00037
#include <stdio.h>
00038
#include <stdlib.h>
00039
00040
#include "avrerror.h"
00041
#include "avrmalloc.h"
00042
#include "avrclass.h"
00043
#include "utils.h"
00044
#include "callback.h"
00045
#include "op_names.h"
00046
00047
#include "storage.h"
00048
#include "flash.h"
00049
00050
#include "vdevs.h"
00051
#include "memory.h"
00052
#include "stack.h"
00053
#include "register.h"
00054
#include "sram.h"
00055
#include "eeprom.h"
00056
#include "timers.h"
00057
#include "ports.h"
00058
00059
#include "avrcore.h"
00060
00061
#include "display.h"
00062
00063
static uint32_t hw_pop (Stack *stack,
int bytes);
00064
static void hw_push (Stack *stack,
int bytes, uint32_t val);
00065
00066
static uint32_t mem_pop (Stack *stack,
int bytes);
00067
static void mem_push (Stack *stack,
int bytes, uint32_t val);
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 Stack *
00081 stack_new (StackFP_Pop pop, StackFP_Push push)
00082 {
00083 Stack *st;
00084
00085 st =
avr_new (Stack, 1);
00086
stack_construct (st, pop, push);
00087
class_overload_destroy ((AvrClass *)st,
stack_destroy);
00088
00089
return st;
00090 }
00091
00092
00093
00094
00095
00096
00097
void
00098 stack_construct (Stack *stack, StackFP_Pop pop, StackFP_Push push)
00099 {
00100
if (stack == NULL)
00101
avr_error (
"passed null ptr");
00102
00103
class_construct ((AvrClass *)stack);
00104
00105 stack->pop = pop;
00106 stack->push = push;
00107 }
00108
00109
00110
00111
00112
00113
00114
void
00115 stack_destroy (
void *stack)
00116 {
00117
if (stack == NULL)
00118
return;
00119
00120
class_destroy (stack);
00121 }
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 uint32_t
00132 stack_pop (Stack *stack,
int bytes)
00133 {
00134
return stack->pop (stack, bytes);
00135 }
00136
00137
00138
00139
00140
00141
00142
00143
00144
void
00145 stack_push (Stack *stack,
int bytes, uint32_t val)
00146 {
00147 stack->push (stack, bytes, val);
00148 }
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 HWStack *
00162 hwstack_new (
int depth)
00163 {
00164 HWStack *st;
00165
00166 st =
avr_new (HWStack, 1);
00167
hwstack_construct (st, depth);
00168
class_overload_destroy ((AvrClass *)st,
hwstack_destroy);
00169
00170
return st;
00171 }
00172
00173
00174
00175
void
00176 hwstack_construct (HWStack *stack,
int depth)
00177 {
00178
if (stack == NULL)
00179
avr_error (
"passed null ptr");
00180
00181
stack_construct ((Stack *)stack, hw_pop, hw_push);
00182
00183 stack->depth = depth;
00184 stack->stack =
avr_new0 (uint32_t, depth);
00185 }
00186
00187
00188
00189
void
00190 hwstack_destroy (
void *stack)
00191 {
00192
if (stack == NULL)
00193
return;
00194
00195
avr_free (((HWStack *)stack)->stack);
00196
stack_destroy (stack);
00197 }
00198
00199
00200
00201
static uint32_t
00202 hw_pop (Stack *stack,
int bytes)
00203 {
00204 HWStack *hwst = (HWStack *)stack;
00205
int i;
00206 uint32_t val = hwst->stack[0];
00207
00208
for (i = 0; i < (hwst->depth - 1); i++)
00209 {
00210 hwst->stack[i] = hwst->stack[i + 1];
00211 }
00212
00213
return val;
00214 }
00215
00216
00217
00218
static void
00219 hw_push (Stack *stack,
int bytes, uint32_t val)
00220 {
00221 HWStack *hwst = (HWStack *)stack;
00222
int i;
00223
00224
for (i = (hwst->depth - 1); i; i--)
00225 {
00226 hwst->stack[i - 1] = hwst->stack[i];
00227 }
00228
00229 hwst->stack[0] = val;
00230 }
00231
00232
00233
00234
00235
00236
00237
00238
#ifndef DOXYGEN
00239
00240
typedef struct _StackPointer StackPointer;
00241
struct _StackPointer
00242 {
00243 VDevice parent;
00244 uint8_t SPL;
00245 uint8_t SPH;
00246 };
00247
00248
#endif
00249
00250
static void sp_construct (StackPointer *sp);
00251
static void sp_destroy (
void *sp);
00252
static uint8_t sp_read (VDevice *dev,
int addr);
00253
static void sp_write (VDevice *dev,
int addr, uint8_t val);
00254
static void sp_reset (VDevice *dev);
00255
static uint16_t sp_get (VDevice *sp);
00256
static void sp_set (VDevice *sp, uint16_t val);
00257
static char *sp_name (VDevice *dev,
int addr);
00258
00259
static StackPointer *
00260 sp_new (
void)
00261 {
00262 StackPointer *sp;
00263
00264 sp =
avr_new (StackPointer, 1);
00265 sp_construct (sp);
00266
class_overload_destroy ((AvrClass *)sp, sp_destroy);
00267
00268
return sp;
00269 }
00270
00271
static void
00272 sp_construct (StackPointer *sp)
00273 {
00274
char *name =
"StackPointer";
00275
00276
if (sp == NULL)
00277
avr_error (
"passed null ptr");
00278
00279
vdev_construct ((VDevice *)sp, name, STACK_POINTER_BASE,
00280 STACK_POINTER_SIZE, sp_read, sp_write, sp_reset, sp_name);
00281
00282 sp_reset ((VDevice *)sp);
00283 }
00284
00285
static void
00286 sp_destroy (
void *sp)
00287 {
00288
if (sp == NULL)
00289
return;
00290
00291
vdev_destroy (sp);
00292 }
00293
00294
static uint8_t
00295 sp_read (VDevice *dev,
int addr)
00296 {
00297 StackPointer *sp = (StackPointer *)dev;
00298
00299
if (0 == (addr -
vdev_get_base (dev)))
00300
return sp->SPL;
00301
else
00302
return sp->SPH;
00303 }
00304
00305
static void
00306 sp_write (VDevice *dev,
int addr, uint8_t val)
00307 {
00308
00309
00310
00311 StackPointer *sp = (StackPointer *)dev;
00312
00313
if (0 == (addr -
vdev_get_base (dev)))
00314 sp->SPL = val;
00315
else
00316 sp->SPH = val;
00317 }
00318
00319
static void
00320 sp_reset (VDevice *dev)
00321 {
00322 StackPointer *sp = (StackPointer *)dev;
00323
00324
display_io_reg (SPL_IO_REG, sp->SPL = 0);
00325
display_io_reg (SPH_IO_REG, sp->SPH = 0);
00326 }
00327
00328
static uint16_t
00329 sp_get (VDevice *sp)
00330 {
00331
return (((StackPointer *)sp)->SPH << 8) + ((StackPointer *)sp)->SPL;
00332 }
00333
00334
static void
00335 sp_set (VDevice *sp, uint16_t val)
00336 {
00337
display_io_reg (SPL_IO_REG, ((StackPointer *)sp)->SPL = val & 0xff);
00338
display_io_reg (SPH_IO_REG, ((StackPointer *)sp)->SPH = val >> 8);
00339 }
00340
00341
static char *
00342 sp_name (VDevice *dev,
int addr)
00343 {
00344
switch (addr)
00345 {
00346
case 0x5d:
00347
return "SPL";
00348
case 0x5e:
00349
return "SPH";
00350 }
00351
return NULL;
00352 }
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 MemStack *
00363 memstack_new (Memory *mem)
00364 {
00365 MemStack *st;
00366
00367 st =
avr_new (MemStack, 1);
00368
memstack_construct (st, mem);
00369
class_overload_destroy ((AvrClass *)st,
memstack_destroy);
00370
00371
return st;
00372 }
00373
00374
00375
00376
void
00377 memstack_construct (MemStack *stack, Memory *mem)
00378 {
00379
if (stack == NULL)
00380
avr_error (
"passed null ptr");
00381
00382
stack_construct ((Stack *)stack, mem_pop, mem_push);
00383
00384
class_ref ((AvrClass *)mem);
00385 stack->mem = mem;
00386
00387
00388 stack->SP = (VDevice *)sp_new ();
00389
mem_attach (stack->mem, stack->SP);
00390 }
00391
00392
00393
00394
void
00395 memstack_destroy (
void *stack)
00396 {
00397 MemStack *_stack = (MemStack *)stack;
00398
00399
if (stack == NULL)
00400
return;
00401
00402
class_unref ((AvrClass *)_stack->SP);
00403
class_unref ((AvrClass *)_stack->mem);
00404
00405
stack_destroy (stack);
00406 }
00407
00408
00409
00410
static uint32_t
00411 mem_pop (Stack *stack,
int bytes)
00412 {
00413 MemStack *mst = (MemStack *)stack;
00414
int i;
00415 uint32_t val = 0;
00416 uint16_t sp = sp_get (mst->SP);
00417
00418
if ((bytes < 0) || (bytes >=
sizeof (uint32_t)))
00419
avr_error (
"bytes out of bounds: %d", bytes);
00420
00421
for (i = bytes - 1; i >= 0; i--)
00422 {
00423 sp++;
00424 val |= (
mem_read (mst->mem, sp) << (i * 8));
00425 }
00426
00427 sp_set (mst->SP, sp);
00428
00429
return val;
00430 }
00431
00432
00433
00434
static void
00435 mem_push (Stack *stack,
int bytes, uint32_t val)
00436 {
00437 MemStack *mst = (MemStack *)stack;
00438
int i;
00439 uint16_t sp = sp_get (mst->SP);
00440
00441
if ((bytes < 0) || (bytes >=
sizeof (uint32_t)))
00442
avr_error (
"bytes out of bounds: %d", bytes);
00443
00444
for (i = 0; i < bytes; i++)
00445 {
00446
mem_write (mst->mem, sp, val & 0xff);
00447 val >>= 8;
00448 sp--;
00449 }
00450
00451 sp_set (mst->SP, sp);
00452 }