2010-09-24 08:47:04 +00:00
|
|
|
/*
|
|
|
|
Copyright (c) 2010 Michael Steil, Brian Silverman, Barry Silverman
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
2010-10-07 02:19:44 +00:00
|
|
|
//#define DEBUG
|
|
|
|
|
2010-09-24 08:47:04 +00:00
|
|
|
/************************************************************
|
|
|
|
*
|
|
|
|
* Libc Functions and Basic Data Types
|
|
|
|
*
|
|
|
|
************************************************************/
|
|
|
|
|
2010-09-22 01:51:38 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2010-10-06 16:53:40 +00:00
|
|
|
#include "perfect6502.h"
|
|
|
|
|
2010-09-22 01:51:38 +00:00
|
|
|
typedef unsigned char uint8_t;
|
2010-09-22 05:14:57 +00:00
|
|
|
typedef unsigned short uint16_t;
|
2010-10-05 16:46:27 +00:00
|
|
|
typedef unsigned int BOOL;
|
2010-09-22 01:51:38 +00:00
|
|
|
|
|
|
|
#define YES 1
|
2010-10-06 02:13:38 +00:00
|
|
|
#define NO 0
|
2010-09-22 01:51:38 +00:00
|
|
|
|
2010-09-24 08:47:04 +00:00
|
|
|
/************************************************************
|
|
|
|
*
|
|
|
|
* 6502 Description: Nodes, Transistors and Probes
|
|
|
|
*
|
|
|
|
************************************************************/
|
|
|
|
|
2010-09-23 08:29:47 +00:00
|
|
|
/* nodes */
|
2010-09-22 01:51:38 +00:00
|
|
|
#include "segdefs.h"
|
2010-09-23 08:29:47 +00:00
|
|
|
/* transistors */
|
2010-09-22 01:51:38 +00:00
|
|
|
#include "transdefs.h"
|
2010-09-23 08:29:47 +00:00
|
|
|
/* node numbers of probes */
|
2010-09-22 01:51:38 +00:00
|
|
|
#include "nodenames.h"
|
|
|
|
|
2010-09-24 08:47:04 +00:00
|
|
|
/* the 6502 consists of this many nodes and transistors */
|
2010-10-06 02:13:38 +00:00
|
|
|
#define NODES (sizeof(segdefs)/sizeof(*segdefs))
|
|
|
|
#define TRANSISTORS (sizeof(transdefs)/sizeof(*transdefs))
|
2010-09-24 08:47:04 +00:00
|
|
|
|
|
|
|
/************************************************************
|
|
|
|
*
|
|
|
|
* Global Data Types
|
|
|
|
*
|
|
|
|
************************************************************/
|
|
|
|
|
2010-09-23 08:29:47 +00:00
|
|
|
/* the smallest types to fit the numbers */
|
|
|
|
typedef uint16_t nodenum_t;
|
|
|
|
typedef uint16_t transnum_t;
|
|
|
|
typedef uint16_t count_t;
|
|
|
|
|
2010-09-25 00:29:11 +00:00
|
|
|
/************************************************************
|
|
|
|
*
|
|
|
|
* Bitmap Data Structures and Algorithms
|
|
|
|
*
|
|
|
|
************************************************************/
|
|
|
|
|
2010-10-06 02:13:38 +00:00
|
|
|
#if 0 /* on 64 bit CPUs */
|
2010-09-25 00:42:44 +00:00
|
|
|
typedef unsigned long long bitmap_t;
|
|
|
|
#define BITMAP_SHIFT 6
|
|
|
|
#define BITMAP_MASK 63
|
2010-10-06 03:00:20 +00:00
|
|
|
#define ONE 1ULL
|
2010-09-25 00:42:44 +00:00
|
|
|
#else
|
2010-09-25 00:29:11 +00:00
|
|
|
typedef unsigned int bitmap_t;
|
2010-09-25 00:42:44 +00:00
|
|
|
#define BITMAP_SHIFT 5
|
|
|
|
#define BITMAP_MASK 31
|
2010-10-06 03:00:20 +00:00
|
|
|
#define ONE 1
|
2010-09-25 00:42:44 +00:00
|
|
|
#endif
|
2010-09-25 00:29:11 +00:00
|
|
|
|
2010-10-06 03:00:20 +00:00
|
|
|
#define WORDS_FOR_BITS(a) (a/(sizeof(bitmap_t) * 8)+1)
|
2010-10-06 02:13:38 +00:00
|
|
|
#define DECLARE_BITMAP(name, count) bitmap_t name[WORDS_FOR_BITS(count)]
|
2010-09-25 00:39:03 +00:00
|
|
|
|
|
|
|
static inline void
|
|
|
|
bitmap_clear(bitmap_t *bitmap, count_t count)
|
|
|
|
{
|
2010-10-06 02:13:38 +00:00
|
|
|
bzero(bitmap, WORDS_FOR_BITS(count)*sizeof(bitmap_t));
|
2010-09-25 00:39:03 +00:00
|
|
|
}
|
|
|
|
|
2010-09-25 00:29:11 +00:00
|
|
|
static inline void
|
|
|
|
set_bitmap(bitmap_t *bitmap, int index, BOOL state)
|
|
|
|
{
|
|
|
|
if (state)
|
2010-10-06 03:00:20 +00:00
|
|
|
bitmap[index>>BITMAP_SHIFT] |= ONE << (index & BITMAP_MASK);
|
2010-09-25 00:29:11 +00:00
|
|
|
else
|
2010-10-06 03:00:20 +00:00
|
|
|
bitmap[index>>BITMAP_SHIFT] &= ~(ONE << (index & BITMAP_MASK));
|
2010-09-25 00:29:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline BOOL
|
|
|
|
get_bitmap(bitmap_t *bitmap, int index)
|
|
|
|
{
|
2010-09-25 00:42:44 +00:00
|
|
|
return (bitmap[index>>BITMAP_SHIFT] >> (index & BITMAP_MASK)) & 1;
|
2010-09-25 00:29:11 +00:00
|
|
|
}
|
|
|
|
|
2010-09-24 08:47:04 +00:00
|
|
|
/************************************************************
|
|
|
|
*
|
|
|
|
* Data Structures for Nodes
|
|
|
|
*
|
|
|
|
************************************************************/
|
|
|
|
|
2010-09-23 08:29:47 +00:00
|
|
|
/* everything that describes a node */
|
2010-09-25 00:39:03 +00:00
|
|
|
DECLARE_BITMAP(nodes_pullup, NODES);
|
|
|
|
DECLARE_BITMAP(nodes_pulldown, NODES);
|
2010-10-05 18:20:02 +00:00
|
|
|
DECLARE_BITMAP(nodes_value, NODES);
|
2010-09-23 00:38:06 +00:00
|
|
|
nodenum_t nodes_gates[NODES][NODES];
|
|
|
|
nodenum_t nodes_c1c2s[NODES][2*NODES];
|
|
|
|
count_t nodes_gatecount[NODES];
|
|
|
|
count_t nodes_c1c2count[NODES];
|
2010-10-07 04:39:40 +00:00
|
|
|
nodenum_t nodes_dependants[NODES];
|
|
|
|
nodenum_t nodes_dependant[NODES][NODES];
|
2010-09-22 01:51:38 +00:00
|
|
|
|
2010-10-05 17:48:01 +00:00
|
|
|
/*
|
2010-10-05 17:54:51 +00:00
|
|
|
* The "value" propertiy of VCC and GND is never evaluated in the code,
|
|
|
|
* so we don't bother initializing it properly or special-casing writes.
|
2010-10-05 17:48:01 +00:00
|
|
|
*/
|
|
|
|
|
2010-09-24 08:55:37 +00:00
|
|
|
static inline void
|
|
|
|
set_nodes_pullup(transnum_t t, BOOL state)
|
|
|
|
{
|
2010-09-25 00:29:11 +00:00
|
|
|
set_bitmap(nodes_pullup, t, state);
|
2010-09-24 08:55:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline BOOL
|
|
|
|
get_nodes_pullup(transnum_t t)
|
|
|
|
{
|
2010-09-25 00:29:11 +00:00
|
|
|
return get_bitmap(nodes_pullup, t);
|
2010-09-24 08:55:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
set_nodes_pulldown(transnum_t t, BOOL state)
|
|
|
|
{
|
2010-09-25 00:29:11 +00:00
|
|
|
set_bitmap(nodes_pulldown, t, state);
|
2010-09-24 08:55:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline BOOL
|
|
|
|
get_nodes_pulldown(transnum_t t)
|
|
|
|
{
|
2010-09-25 00:29:11 +00:00
|
|
|
return get_bitmap(nodes_pulldown, t);
|
2010-09-24 08:55:37 +00:00
|
|
|
}
|
|
|
|
|
2010-09-24 10:44:49 +00:00
|
|
|
static inline void
|
2010-10-05 18:20:02 +00:00
|
|
|
set_nodes_value(transnum_t t, BOOL state)
|
2010-09-24 10:44:49 +00:00
|
|
|
{
|
2010-10-05 18:20:02 +00:00
|
|
|
set_bitmap(nodes_value, t, state);
|
2010-09-24 10:44:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline BOOL
|
2010-10-05 18:20:02 +00:00
|
|
|
get_nodes_value(transnum_t t)
|
2010-09-24 10:44:49 +00:00
|
|
|
{
|
2010-10-05 18:20:02 +00:00
|
|
|
return get_bitmap(nodes_value, t);
|
2010-09-24 10:44:49 +00:00
|
|
|
}
|
|
|
|
|
2010-09-23 08:29:47 +00:00
|
|
|
/************************************************************
|
|
|
|
*
|
2010-09-24 08:47:04 +00:00
|
|
|
* Data Structures and Algorithms for Transistors
|
2010-09-23 08:29:47 +00:00
|
|
|
*
|
|
|
|
************************************************************/
|
2010-09-22 23:14:18 +00:00
|
|
|
|
2010-09-24 08:47:04 +00:00
|
|
|
/* everything that describes a transistor */
|
|
|
|
nodenum_t transistors_gate[TRANSISTORS];
|
|
|
|
nodenum_t transistors_c1[TRANSISTORS];
|
|
|
|
nodenum_t transistors_c2[TRANSISTORS];
|
2010-09-25 00:39:03 +00:00
|
|
|
DECLARE_BITMAP(transistors_on, TRANSISTORS);
|
2010-09-24 08:47:04 +00:00
|
|
|
|
|
|
|
static inline void
|
2010-09-22 23:14:18 +00:00
|
|
|
set_transistors_on(transnum_t t, BOOL state)
|
|
|
|
{
|
2010-10-07 04:39:40 +00:00
|
|
|
#ifdef BROKEN_TRANSISTORS
|
|
|
|
if (t == broken_transistor)
|
|
|
|
return;
|
|
|
|
#endif
|
2010-09-25 00:29:11 +00:00
|
|
|
set_bitmap(transistors_on, t, state);
|
2010-09-22 23:14:18 +00:00
|
|
|
}
|
|
|
|
|
2010-09-24 08:47:04 +00:00
|
|
|
static inline BOOL
|
2010-09-22 23:14:18 +00:00
|
|
|
get_transistors_on(transnum_t t)
|
|
|
|
{
|
2010-09-25 00:29:11 +00:00
|
|
|
return get_bitmap(transistors_on, t);
|
2010-09-22 23:14:18 +00:00
|
|
|
}
|
2010-09-22 01:51:38 +00:00
|
|
|
|
2010-09-24 00:42:51 +00:00
|
|
|
/************************************************************
|
|
|
|
*
|
|
|
|
* Data Structures and Algorithms for Lists
|
|
|
|
*
|
|
|
|
************************************************************/
|
|
|
|
|
|
|
|
/* list of nodes that need to be recalculated */
|
|
|
|
typedef struct {
|
|
|
|
nodenum_t *list;
|
|
|
|
count_t count;
|
|
|
|
} list_t;
|
|
|
|
|
2010-09-24 08:27:20 +00:00
|
|
|
/* the nodes we are working with */
|
2010-09-24 00:42:51 +00:00
|
|
|
nodenum_t list1[NODES];
|
2010-09-24 08:27:20 +00:00
|
|
|
list_t listin = {
|
|
|
|
.list = list1,
|
2010-09-24 00:42:51 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* the nodes we are collecting for the next run */
|
2010-09-24 08:27:20 +00:00
|
|
|
nodenum_t list2[NODES];
|
|
|
|
list_t listout = {
|
|
|
|
.list = list2,
|
2010-09-24 00:42:51 +00:00
|
|
|
};
|
|
|
|
|
2010-09-24 08:47:04 +00:00
|
|
|
static inline nodenum_t
|
2010-09-24 08:27:20 +00:00
|
|
|
listin_get(count_t i)
|
|
|
|
{
|
|
|
|
return listin.list[i];
|
|
|
|
}
|
|
|
|
|
2010-09-24 08:47:04 +00:00
|
|
|
static inline count_t
|
2010-09-24 08:27:20 +00:00
|
|
|
listin_count()
|
|
|
|
{
|
|
|
|
return listin.count;
|
2010-09-24 00:42:51 +00:00
|
|
|
}
|
|
|
|
|
2010-09-24 08:47:04 +00:00
|
|
|
static inline void
|
2010-09-24 08:27:20 +00:00
|
|
|
lists_switch()
|
2010-09-24 00:42:51 +00:00
|
|
|
{
|
2010-09-24 08:27:20 +00:00
|
|
|
list_t tmp = listin;
|
|
|
|
listin = listout;
|
|
|
|
listout = tmp;
|
2010-09-24 00:42:51 +00:00
|
|
|
}
|
|
|
|
|
2010-09-24 08:27:20 +00:00
|
|
|
static inline void
|
|
|
|
listout_clear()
|
2010-09-24 00:28:59 +00:00
|
|
|
{
|
2010-09-24 08:27:20 +00:00
|
|
|
listout.count = 0;
|
2010-09-24 00:28:59 +00:00
|
|
|
}
|
|
|
|
|
2010-10-06 03:00:20 +00:00
|
|
|
static inline void
|
|
|
|
listout_add(nodenum_t i)
|
|
|
|
{
|
2010-10-08 03:22:54 +00:00
|
|
|
listout.list[listout.count++] = i;
|
2010-10-06 03:00:20 +00:00
|
|
|
}
|
|
|
|
|
2010-09-24 00:28:59 +00:00
|
|
|
/************************************************************
|
|
|
|
*
|
|
|
|
* Data Structures and Algorithms for Groups of Nodes
|
|
|
|
*
|
|
|
|
************************************************************/
|
|
|
|
|
|
|
|
/*
|
2010-10-05 16:27:33 +00:00
|
|
|
* a group is a set of connected nodes, which consequently
|
|
|
|
* share the same potential
|
2010-09-24 00:28:59 +00:00
|
|
|
*
|
|
|
|
* we use an array and a count for O(1) insert and
|
|
|
|
* iteration, and a redundant bitmap for O(1) lookup
|
|
|
|
*/
|
|
|
|
static nodenum_t group[NODES];
|
|
|
|
static count_t groupcount;
|
2010-09-25 00:39:03 +00:00
|
|
|
DECLARE_BITMAP(groupbitmap, NODES);
|
2010-09-24 00:28:59 +00:00
|
|
|
|
|
|
|
static inline void
|
2010-09-24 08:27:20 +00:00
|
|
|
group_clear()
|
2010-09-24 00:28:59 +00:00
|
|
|
{
|
|
|
|
groupcount = 0;
|
2010-09-25 00:39:03 +00:00
|
|
|
bitmap_clear(groupbitmap, NODES);
|
2010-09-24 00:28:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
group_add(nodenum_t i)
|
|
|
|
{
|
|
|
|
group[groupcount++] = i;
|
2010-09-25 00:30:55 +00:00
|
|
|
set_bitmap(groupbitmap, i, 1);
|
2010-09-24 00:28:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline nodenum_t
|
|
|
|
group_get(count_t n)
|
|
|
|
{
|
|
|
|
return group[n];
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline BOOL
|
|
|
|
group_contains(nodenum_t el)
|
2010-09-22 01:51:38 +00:00
|
|
|
{
|
2010-09-25 00:30:55 +00:00
|
|
|
return get_bitmap(groupbitmap, el);
|
2010-09-22 01:51:38 +00:00
|
|
|
}
|
|
|
|
|
2010-09-24 00:28:59 +00:00
|
|
|
static inline count_t
|
|
|
|
group_count()
|
2010-09-22 18:00:45 +00:00
|
|
|
{
|
2010-09-24 00:28:59 +00:00
|
|
|
return groupcount;
|
2010-09-22 18:00:45 +00:00
|
|
|
}
|
|
|
|
|
2010-09-24 11:09:05 +00:00
|
|
|
/************************************************************
|
|
|
|
*
|
|
|
|
* Node State
|
|
|
|
*
|
|
|
|
************************************************************/
|
|
|
|
|
|
|
|
void recalcNodeList(const nodenum_t *source, count_t count);
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
setNode(nodenum_t nn, BOOL state)
|
|
|
|
{
|
|
|
|
set_nodes_pullup(nn, state);
|
|
|
|
set_nodes_pulldown(nn, !state);
|
|
|
|
recalcNodeList(&nn, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline BOOL
|
|
|
|
isNodeHigh(nodenum_t nn)
|
|
|
|
{
|
2010-10-05 18:20:02 +00:00
|
|
|
return get_nodes_value(nn);
|
2010-09-24 11:09:05 +00:00
|
|
|
}
|
|
|
|
|
2010-09-23 08:29:47 +00:00
|
|
|
/************************************************************
|
|
|
|
*
|
|
|
|
* Node and Transistor Emulation
|
|
|
|
*
|
|
|
|
************************************************************/
|
|
|
|
|
2010-10-07 05:20:49 +00:00
|
|
|
BOOL group_contains_pullup;
|
|
|
|
BOOL group_contains_pulldown;
|
|
|
|
BOOL group_contains_hi;
|
2010-09-22 01:51:38 +00:00
|
|
|
|
|
|
|
void
|
2010-10-07 05:20:49 +00:00
|
|
|
addNodeToGroup(nodenum_t n)
|
2010-09-22 01:51:38 +00:00
|
|
|
{
|
2010-10-07 05:20:49 +00:00
|
|
|
if (group_contains(n))
|
2010-09-22 01:51:38 +00:00
|
|
|
return;
|
2010-09-23 00:38:06 +00:00
|
|
|
|
2010-10-07 05:20:49 +00:00
|
|
|
group_add(n);
|
2010-09-22 01:51:38 +00:00
|
|
|
|
2010-10-07 05:20:49 +00:00
|
|
|
if (get_nodes_pullup(n))
|
|
|
|
group_contains_pullup = YES;
|
|
|
|
if (get_nodes_pulldown(n))
|
|
|
|
group_contains_pulldown = YES;
|
|
|
|
if (get_nodes_value(n))
|
|
|
|
group_contains_hi = YES;
|
2010-09-23 03:21:13 +00:00
|
|
|
|
2010-10-07 05:20:49 +00:00
|
|
|
if (n == vss || n == vcc)
|
|
|
|
return;
|
2010-09-23 03:21:13 +00:00
|
|
|
|
2010-10-05 18:01:13 +00:00
|
|
|
/* revisit all transistors that are controlled by this node */
|
2010-10-07 05:20:49 +00:00
|
|
|
for (count_t t = 0; t < nodes_c1c2count[n]; t++) {
|
|
|
|
transnum_t tn = nodes_c1c2s[n][t];
|
|
|
|
/* if the transistor connects c1 and c2... */
|
|
|
|
if (get_transistors_on(tn)) {
|
|
|
|
/* if original node was connected to c1, continue with c2 */
|
|
|
|
if (transistors_c1[tn] == n)
|
|
|
|
addNodeToGroup(transistors_c2[tn]);
|
|
|
|
else
|
|
|
|
addNodeToGroup(transistors_c1[tn]);
|
|
|
|
}
|
|
|
|
}
|
2010-09-22 01:51:38 +00:00
|
|
|
}
|
|
|
|
|
2010-10-06 03:00:20 +00:00
|
|
|
static inline void
|
|
|
|
addAllNodesToGroup(node)
|
|
|
|
{
|
|
|
|
group_clear();
|
2010-10-07 05:20:49 +00:00
|
|
|
|
|
|
|
group_contains_pullup = NO;
|
|
|
|
group_contains_pulldown = NO;
|
|
|
|
group_contains_hi = NO;
|
|
|
|
|
2010-10-06 03:00:20 +00:00
|
|
|
addNodeToGroup(node);
|
|
|
|
}
|
2010-10-05 16:46:27 +00:00
|
|
|
|
2010-10-05 17:54:51 +00:00
|
|
|
static inline BOOL
|
2010-10-05 18:01:13 +00:00
|
|
|
getGroupValue()
|
2010-09-22 01:51:38 +00:00
|
|
|
{
|
2010-10-05 16:54:12 +00:00
|
|
|
if (group_contains(vss))
|
2010-10-05 17:54:51 +00:00
|
|
|
return NO;
|
2010-10-05 16:46:27 +00:00
|
|
|
|
2010-10-05 16:54:12 +00:00
|
|
|
if (group_contains(vcc))
|
2010-10-05 17:54:51 +00:00
|
|
|
return YES;
|
2010-09-23 08:29:47 +00:00
|
|
|
|
2010-10-05 17:48:01 +00:00
|
|
|
if (group_contains_pulldown)
|
2010-10-05 17:54:51 +00:00
|
|
|
return NO;
|
2010-10-05 16:54:12 +00:00
|
|
|
|
2010-10-05 17:48:01 +00:00
|
|
|
if (group_contains_pullup)
|
2010-10-05 17:54:51 +00:00
|
|
|
return YES;
|
2010-10-05 16:54:12 +00:00
|
|
|
|
2010-10-05 18:01:13 +00:00
|
|
|
return group_contains_hi;
|
2010-09-22 01:51:38 +00:00
|
|
|
}
|
|
|
|
|
2010-09-28 17:22:57 +00:00
|
|
|
#ifdef BROKEN_TRANSISTORS
|
2010-10-06 16:53:40 +00:00
|
|
|
unsigned int broken_transistor = (unsigned int)-1;
|
2010-09-28 17:22:57 +00:00
|
|
|
#endif
|
|
|
|
|
2010-09-22 01:51:38 +00:00
|
|
|
void
|
2010-09-22 22:57:00 +00:00
|
|
|
recalcNode(nodenum_t node)
|
2010-09-22 01:51:38 +00:00
|
|
|
{
|
2010-09-23 03:28:00 +00:00
|
|
|
/*
|
|
|
|
* get all nodes that are connected through
|
|
|
|
* transistors, starting with this one
|
|
|
|
*/
|
2010-10-06 03:00:20 +00:00
|
|
|
addAllNodesToGroup(node);
|
2010-09-22 01:51:38 +00:00
|
|
|
|
2010-10-07 02:19:44 +00:00
|
|
|
#ifdef DEBUG
|
|
|
|
printf(" %s node %d -> ", __func__, node);
|
|
|
|
for (count_t j = 0; j < group_count(); j++)
|
|
|
|
printf("%d ", group_get(j));
|
|
|
|
printf("\n");
|
|
|
|
#endif
|
|
|
|
|
2010-09-23 03:28:00 +00:00
|
|
|
/* get the state of the group */
|
2010-10-05 18:01:13 +00:00
|
|
|
BOOL newv = getGroupValue();
|
2010-10-05 16:46:27 +00:00
|
|
|
|
2010-09-23 03:28:00 +00:00
|
|
|
/*
|
2010-10-06 03:00:20 +00:00
|
|
|
* - set all nodes to the group state
|
|
|
|
* - check all transistors switched by nodes of the group
|
|
|
|
* - collect all nodes behind toggled transistors
|
|
|
|
* for the next run
|
2010-09-23 03:28:00 +00:00
|
|
|
*/
|
2010-09-24 00:28:59 +00:00
|
|
|
for (count_t i = 0; i < group_count(); i++) {
|
|
|
|
nodenum_t nn = group_get(i);
|
2010-10-05 18:20:02 +00:00
|
|
|
if (get_nodes_value(nn) != newv) {
|
|
|
|
set_nodes_value(nn, newv);
|
2010-10-07 04:39:40 +00:00
|
|
|
for (count_t t = 0; t < nodes_gatecount[nn]; t++) {
|
|
|
|
transnum_t tn = nodes_gates[nn][t];
|
|
|
|
set_transistors_on(tn, !get_transistors_on(tn));
|
|
|
|
}
|
2010-10-07 05:20:49 +00:00
|
|
|
#if 0
|
2010-10-07 04:39:40 +00:00
|
|
|
for (count_t g = 0; g < nodes_dependants[nn]; g++)
|
|
|
|
listout_add(nodes_dependant[nn][g]);
|
2010-10-07 05:20:49 +00:00
|
|
|
#else
|
2010-10-08 03:22:54 +00:00
|
|
|
listout_add(nn);
|
2010-10-07 05:20:49 +00:00
|
|
|
#endif
|
2010-10-05 18:13:48 +00:00
|
|
|
}
|
2010-09-22 05:14:57 +00:00
|
|
|
}
|
2010-10-07 05:20:49 +00:00
|
|
|
#ifdef DEBUG
|
|
|
|
printf("(%d)\n", listout.count);
|
|
|
|
#endif
|
2010-09-22 01:51:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2010-09-24 09:42:17 +00:00
|
|
|
recalcNodeList(const nodenum_t *source, count_t count)
|
2010-09-22 01:51:38 +00:00
|
|
|
{
|
2010-10-08 03:22:54 +00:00
|
|
|
listout_clear();
|
|
|
|
|
|
|
|
for (count_t i = 0; i < count; i++)
|
|
|
|
recalcNode(source[i]);
|
2010-09-24 09:42:17 +00:00
|
|
|
|
2010-10-08 03:22:54 +00:00
|
|
|
lists_switch();
|
|
|
|
|
|
|
|
for (int j = 0; j < 100; j++) { /* loop limiter */
|
2010-10-07 02:19:44 +00:00
|
|
|
#ifdef DEBUG
|
|
|
|
printf("%s iteration=%d, count=%d\n", __func__, j, listin_count());
|
|
|
|
#endif
|
2010-10-05 18:13:48 +00:00
|
|
|
if (!listin_count())
|
|
|
|
break;
|
2010-09-23 02:53:11 +00:00
|
|
|
|
2010-09-24 08:27:20 +00:00
|
|
|
listout_clear();
|
2010-09-22 18:00:45 +00:00
|
|
|
|
2010-09-23 06:44:32 +00:00
|
|
|
/*
|
|
|
|
* for all nodes, follow their paths through
|
|
|
|
* turned-on transistors, find the state of the
|
|
|
|
* path and assign it to all nodes, and re-evaluate
|
|
|
|
* all transistors controlled by this path, collecting
|
|
|
|
* all nodes that changed because of it for the next run
|
|
|
|
*/
|
2010-10-07 05:20:49 +00:00
|
|
|
for (count_t i = 0; i < listin_count(); i++) {
|
|
|
|
nodenum_t n = listin_get(i);
|
2010-10-08 03:22:54 +00:00
|
|
|
for (count_t g = 0; g < nodes_dependants[n]; g++) {
|
|
|
|
recalcNode(nodes_dependant[n][g]);
|
2010-10-07 05:20:49 +00:00
|
|
|
}
|
|
|
|
}
|
2010-09-23 06:44:32 +00:00
|
|
|
/*
|
|
|
|
* make the secondary list our primary list, use
|
|
|
|
* the data storage of the primary list as the
|
|
|
|
* secondary list
|
|
|
|
*/
|
2010-09-24 08:27:20 +00:00
|
|
|
lists_switch();
|
2010-09-22 01:51:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
recalcAllNodes()
|
|
|
|
{
|
2010-09-24 08:27:20 +00:00
|
|
|
nodenum_t temp[NODES];
|
2010-09-23 06:44:32 +00:00
|
|
|
for (count_t i = 0; i < NODES; i++)
|
2010-09-24 08:27:20 +00:00
|
|
|
temp[i] = i;
|
2010-09-24 09:42:17 +00:00
|
|
|
recalcNodeList(temp, NODES);
|
2010-09-22 01:51:38 +00:00
|
|
|
}
|
|
|
|
|
2010-09-23 06:56:23 +00:00
|
|
|
/************************************************************
|
|
|
|
*
|
|
|
|
* Address Bus and Data Bus Interface
|
|
|
|
*
|
|
|
|
************************************************************/
|
|
|
|
|
2010-10-06 03:00:20 +00:00
|
|
|
uint8_t memory[65536];
|
2010-09-24 08:47:04 +00:00
|
|
|
|
2010-09-23 06:44:32 +00:00
|
|
|
/* the nodes that make the data bus */
|
|
|
|
const nodenum_t dbnodes[8] = { db0, db1, db2, db3, db4, db5, db6, db7 };
|
2010-09-23 02:47:31 +00:00
|
|
|
|
2010-09-22 05:14:57 +00:00
|
|
|
void
|
2010-09-24 09:42:17 +00:00
|
|
|
writeDataBus(uint8_t d)
|
2010-09-22 01:51:38 +00:00
|
|
|
{
|
2010-09-23 02:47:31 +00:00
|
|
|
for (int i = 0; i < 8; i++) {
|
2010-10-06 03:00:20 +00:00
|
|
|
setNode(dbnodes[i], d & 1);
|
2010-09-24 09:42:17 +00:00
|
|
|
d >>= 1;
|
2010-09-22 05:14:57 +00:00
|
|
|
}
|
2010-09-23 06:44:32 +00:00
|
|
|
|
2010-09-23 06:56:23 +00:00
|
|
|
/* recalc all nodes connected starting from the data bus */
|
2010-09-24 09:42:17 +00:00
|
|
|
recalcNodeList(dbnodes, 8);
|
2010-09-22 05:14:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t mRead(uint16_t a)
|
|
|
|
{
|
|
|
|
return memory[a];
|
|
|
|
}
|
|
|
|
|
2010-10-07 02:19:44 +00:00
|
|
|
#define read8(n0,n1,n2,n3,n4,n5,n6,n7) ((uint8_t)(isNodeHigh(n0) << 0) | (isNodeHigh(n1) << 1) | (isNodeHigh(n2) << 2) | (isNodeHigh(n3) << 3) | (isNodeHigh(n4) << 4) | (isNodeHigh(n5) << 5) | (isNodeHigh(n6) << 6) | (isNodeHigh(n7) << 7))
|
|
|
|
|
2010-09-22 05:14:57 +00:00
|
|
|
uint16_t
|
|
|
|
readAddressBus()
|
|
|
|
{
|
2010-10-07 02:19:44 +00:00
|
|
|
return read8(ab0,ab1,ab2,ab3,ab4,ab5,ab6,ab7) | (read8(ab8,ab9,ab10,ab11,ab12,ab13,ab14,ab15) << 8);
|
2010-09-22 01:51:38 +00:00
|
|
|
}
|
|
|
|
|
2010-09-22 05:14:57 +00:00
|
|
|
uint8_t
|
|
|
|
readDataBus()
|
|
|
|
{
|
2010-10-07 02:19:44 +00:00
|
|
|
return read8(db0,db1,db2,db3,db4,db5,db6,db7);
|
2010-09-22 05:14:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
mWrite(uint16_t a, uint8_t d)
|
|
|
|
{
|
|
|
|
memory[a] = d;
|
2010-09-22 01:51:38 +00:00
|
|
|
}
|
|
|
|
|
2010-10-06 03:00:20 +00:00
|
|
|
static inline void
|
|
|
|
handleMemory()
|
|
|
|
{
|
|
|
|
if (isNodeHigh(rw))
|
|
|
|
writeDataBus(mRead(readAddressBus()));
|
|
|
|
else
|
|
|
|
mWrite(readAddressBus(), readDataBus());
|
|
|
|
}
|
|
|
|
|
2010-09-23 06:56:23 +00:00
|
|
|
/************************************************************
|
|
|
|
*
|
|
|
|
* Tracing/Debugging
|
|
|
|
*
|
|
|
|
************************************************************/
|
2010-10-06 04:32:54 +00:00
|
|
|
|
2010-09-22 05:14:57 +00:00
|
|
|
uint8_t
|
|
|
|
readA()
|
|
|
|
{
|
2010-10-06 04:32:54 +00:00
|
|
|
return read8(a0,a1,a2,a3,a4,a5,a6,a7);
|
2010-09-22 05:14:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t
|
|
|
|
readX()
|
|
|
|
{
|
2010-10-06 04:32:54 +00:00
|
|
|
return read8(x0,x1,x2,x3,x4,x5,x6,x7);
|
2010-09-22 05:14:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t
|
|
|
|
readY()
|
|
|
|
{
|
2010-10-06 04:32:54 +00:00
|
|
|
return read8(y0,y1,y2,y3,y4,y5,y6,y7);
|
2010-09-22 05:14:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t
|
|
|
|
readP()
|
|
|
|
{
|
2010-10-06 04:32:54 +00:00
|
|
|
return read8(p0,p1,p2,p3,p4,p5,p6,p7);
|
2010-09-22 05:14:57 +00:00
|
|
|
}
|
|
|
|
|
2010-09-22 15:25:34 +00:00
|
|
|
uint8_t
|
2010-10-06 16:33:26 +00:00
|
|
|
readIR()
|
2010-09-22 15:25:34 +00:00
|
|
|
{
|
2010-10-07 02:19:44 +00:00
|
|
|
return read8(notir0,notir1,notir2,notir3,notir4,notir5,notir6,notir7) ^ 0xFF;
|
2010-09-22 15:25:34 +00:00
|
|
|
}
|
|
|
|
|
2010-09-22 05:14:57 +00:00
|
|
|
uint8_t
|
|
|
|
readSP()
|
|
|
|
{
|
2010-10-06 04:32:54 +00:00
|
|
|
return read8(s0,s1,s2,s3,s4,s5,s6,s7);
|
2010-09-22 05:14:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t
|
|
|
|
readPCL()
|
|
|
|
{
|
2010-10-06 04:32:54 +00:00
|
|
|
return read8(pcl0,pcl1,pcl2,pcl3,pcl4,pcl5,pcl6,pcl7);
|
2010-09-22 05:14:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t
|
|
|
|
readPCH()
|
|
|
|
{
|
2010-10-06 04:32:54 +00:00
|
|
|
return read8(pch0,pch1,pch2,pch3,pch4,pch5,pch6,pch7);
|
2010-09-22 05:14:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint16_t
|
|
|
|
readPC()
|
|
|
|
{
|
|
|
|
return (readPCH() << 8) | readPCL();
|
2010-09-22 01:51:38 +00:00
|
|
|
}
|
|
|
|
|
2010-10-06 16:33:26 +00:00
|
|
|
BOOL
|
|
|
|
readRW()
|
|
|
|
{
|
|
|
|
return isNodeHigh(rw);
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int cycle;
|
2010-09-24 08:47:04 +00:00
|
|
|
|
2010-09-22 01:51:38 +00:00
|
|
|
void
|
|
|
|
chipStatus()
|
|
|
|
{
|
2010-10-06 04:32:54 +00:00
|
|
|
BOOL clk = isNodeHigh(clk0);
|
|
|
|
uint16_t a = readAddressBus();
|
|
|
|
uint8_t d = readDataBus();
|
|
|
|
BOOL r_w = isNodeHigh(rw);
|
|
|
|
|
2010-09-25 21:34:53 +00:00
|
|
|
printf("halfcyc:%d phi0:%d AB:%04X D:%02X RnW:%d PC:%04X A:%02X X:%02X Y:%02X SP:%02X P:%02X IR:%02X",
|
2010-09-22 05:14:57 +00:00
|
|
|
cycle,
|
2010-10-06 04:32:54 +00:00
|
|
|
clk,
|
|
|
|
a,
|
|
|
|
d,
|
|
|
|
r_w,
|
2010-09-22 05:14:57 +00:00
|
|
|
readPC(),
|
|
|
|
readA(),
|
|
|
|
readX(),
|
|
|
|
readY(),
|
|
|
|
readSP(),
|
2010-09-22 15:25:34 +00:00
|
|
|
readP(),
|
2010-10-06 16:33:26 +00:00
|
|
|
readIR());
|
2010-09-25 21:34:53 +00:00
|
|
|
|
2010-09-29 03:19:56 +00:00
|
|
|
if (clk)
|
2010-10-06 04:32:54 +00:00
|
|
|
if (r_w)
|
|
|
|
printf(" R$%04X=$%02X", a, memory[a]);
|
|
|
|
else
|
|
|
|
printf(" W$%04X=$%02X", a, d);
|
|
|
|
printf("\n");
|
2010-09-22 01:51:38 +00:00
|
|
|
}
|
|
|
|
|
2010-09-23 07:45:42 +00:00
|
|
|
/************************************************************
|
|
|
|
*
|
2010-09-23 08:06:26 +00:00
|
|
|
* Main Clock Loop
|
2010-09-23 07:45:42 +00:00
|
|
|
*
|
|
|
|
************************************************************/
|
|
|
|
|
2010-09-22 01:51:38 +00:00
|
|
|
void
|
2010-10-05 16:27:33 +00:00
|
|
|
step()
|
2010-09-22 01:51:38 +00:00
|
|
|
{
|
2010-09-23 08:06:26 +00:00
|
|
|
BOOL clk = isNodeHigh(clk0);
|
2010-09-23 07:45:42 +00:00
|
|
|
|
2010-09-23 08:06:26 +00:00
|
|
|
/* invert clock */
|
|
|
|
setNode(clk0, !clk);
|
2010-09-23 07:45:42 +00:00
|
|
|
|
2010-09-23 08:06:26 +00:00
|
|
|
/* handle memory reads and writes */
|
2010-10-06 03:00:20 +00:00
|
|
|
if (!clk)
|
|
|
|
handleMemory();
|
2010-09-22 01:51:38 +00:00
|
|
|
|
2010-09-23 07:45:42 +00:00
|
|
|
cycle++;
|
2010-10-07 02:19:44 +00:00
|
|
|
|
|
|
|
#if 0
|
|
|
|
int total = 0;
|
|
|
|
for (count_t i = 0; i < NODES; i++) {
|
|
|
|
addAllNodesToGroup(i);
|
|
|
|
printf("%d: ", i);
|
|
|
|
total += group_count();
|
|
|
|
for (count_t j = 0; j < group_count(); j++) {
|
|
|
|
printf("%d ", group_get(j));
|
|
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
printf("TOTAL %f\n", ((float)total)/NODES);
|
|
|
|
#endif
|
2010-09-23 07:45:42 +00:00
|
|
|
}
|
|
|
|
|
2010-09-23 08:06:26 +00:00
|
|
|
/************************************************************
|
|
|
|
*
|
|
|
|
* Initialization
|
|
|
|
*
|
|
|
|
************************************************************/
|
|
|
|
|
2010-10-06 16:53:40 +00:00
|
|
|
unsigned int transistors;
|
2010-09-28 17:22:57 +00:00
|
|
|
|
2010-10-07 04:39:40 +00:00
|
|
|
static inline void
|
|
|
|
add_nodes_dependant(nodenum_t a, nodenum_t b)
|
|
|
|
{
|
|
|
|
for (count_t g = 0; g < nodes_dependants[a]; g++)
|
|
|
|
if (nodes_dependant[a][g] == b)
|
|
|
|
return;
|
|
|
|
|
|
|
|
nodes_dependant[a][nodes_dependants[a]++] = b;
|
|
|
|
}
|
|
|
|
|
2010-09-23 08:29:47 +00:00
|
|
|
void
|
|
|
|
setupNodesAndTransistors()
|
|
|
|
{
|
|
|
|
count_t i;
|
2010-09-25 00:52:48 +00:00
|
|
|
/* copy nodes into r/w data structure */
|
2010-10-06 02:13:38 +00:00
|
|
|
for (i = 0; i < NODES; i++) {
|
2010-09-24 08:55:37 +00:00
|
|
|
set_nodes_pullup(i, segdefs[i] == 1);
|
2010-09-23 08:29:47 +00:00
|
|
|
nodes_gatecount[i] = 0;
|
|
|
|
nodes_c1c2count[i] = 0;
|
|
|
|
}
|
2010-09-25 00:52:48 +00:00
|
|
|
/* copy transistors into r/w data structure */
|
2010-09-25 18:52:18 +00:00
|
|
|
count_t j = 0;
|
2010-10-06 02:13:38 +00:00
|
|
|
for (i = 0; i < TRANSISTORS; i++) {
|
2010-09-25 00:52:48 +00:00
|
|
|
nodenum_t gate = transdefs[i].gate;
|
|
|
|
nodenum_t c1 = transdefs[i].c1;
|
|
|
|
nodenum_t c2 = transdefs[i].c2;
|
2010-09-25 18:52:18 +00:00
|
|
|
/* skip duplicate transistors */
|
|
|
|
BOOL found = NO;
|
2010-09-28 17:22:57 +00:00
|
|
|
#ifndef BROKEN_TRANSISTORS
|
2010-09-25 18:52:18 +00:00
|
|
|
for (count_t k = 0; k < i; k++) {
|
|
|
|
if (transdefs[k].gate == gate &&
|
2010-10-07 02:19:44 +00:00
|
|
|
((transdefs[k].c1 == c1 &&
|
|
|
|
transdefs[k].c2 == c2) ||
|
|
|
|
(transdefs[k].c1 == c2 &&
|
|
|
|
transdefs[k].c2 == c1))) {
|
2010-09-25 18:52:18 +00:00
|
|
|
found = YES;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2010-09-28 17:22:57 +00:00
|
|
|
#endif
|
2010-09-25 18:52:18 +00:00
|
|
|
if (!found) {
|
|
|
|
transistors_gate[j] = gate;
|
|
|
|
transistors_c1[j] = c1;
|
|
|
|
transistors_c2[j] = c2;
|
|
|
|
j++;
|
|
|
|
}
|
2010-09-23 08:29:47 +00:00
|
|
|
}
|
2010-09-28 17:22:57 +00:00
|
|
|
transistors = j;
|
2010-10-07 02:19:44 +00:00
|
|
|
#ifdef DEBUG
|
|
|
|
printf("transistors: %d\n", transistors);
|
|
|
|
#endif
|
2010-09-25 18:52:18 +00:00
|
|
|
|
2010-09-25 00:52:48 +00:00
|
|
|
/* cross reference transistors in nodes data structures */
|
2010-09-27 17:31:20 +00:00
|
|
|
for (i = 0; i < transistors; i++) {
|
2010-09-25 00:52:48 +00:00
|
|
|
nodenum_t gate = transistors_gate[i];
|
|
|
|
nodenum_t c1 = transistors_c1[i];
|
|
|
|
nodenum_t c2 = transistors_c2[i];
|
|
|
|
nodes_gates[gate][nodes_gatecount[gate]++] = i;
|
|
|
|
nodes_c1c2s[c1][nodes_c1c2count[c1]++] = i;
|
|
|
|
nodes_c1c2s[c2][nodes_c1c2count[c2]++] = i;
|
|
|
|
}
|
2010-10-07 02:19:44 +00:00
|
|
|
|
2010-10-07 04:39:40 +00:00
|
|
|
for (i = 0; i < NODES; i++) {
|
|
|
|
nodes_dependants[i] = 0;
|
|
|
|
for (count_t g = 0; g < nodes_gatecount[i]; g++) {
|
|
|
|
transnum_t t = nodes_gates[i][g];
|
|
|
|
add_nodes_dependant(i, transistors_c1[t]);
|
|
|
|
add_nodes_dependant(i, transistors_c2[t]);
|
|
|
|
}
|
|
|
|
}
|
2010-10-07 02:19:44 +00:00
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
for (i = 0; i < NODES; i++) {
|
|
|
|
printf("%d: ", i);
|
2010-10-07 04:39:40 +00:00
|
|
|
for (count_t g = 0; g < nodes_dependants[i]; g++) {
|
|
|
|
printf("%d ", nodes_dependant[i][g]);
|
2010-10-07 02:19:44 +00:00
|
|
|
}
|
2010-10-07 04:39:40 +00:00
|
|
|
printf("(%d)\n", nodes_dependants[i]);
|
2010-10-07 02:19:44 +00:00
|
|
|
}
|
|
|
|
#endif
|
2010-09-23 08:29:47 +00:00
|
|
|
}
|
|
|
|
|
2010-09-23 07:45:42 +00:00
|
|
|
void
|
2010-09-30 02:39:11 +00:00
|
|
|
resetChip()
|
2010-09-22 01:51:38 +00:00
|
|
|
{
|
2010-10-05 17:54:51 +00:00
|
|
|
/* all nodes are down */
|
2010-09-24 10:44:49 +00:00
|
|
|
for (nodenum_t nn = 0; nn < NODES; nn++) {
|
2010-10-05 18:20:02 +00:00
|
|
|
set_nodes_value(nn, 0);
|
2010-09-24 10:44:49 +00:00
|
|
|
}
|
2010-09-23 08:06:26 +00:00
|
|
|
/* all transistors are off */
|
|
|
|
for (transnum_t tn = 0; tn < TRANSISTORS; tn++)
|
|
|
|
set_transistors_on(tn, NO);
|
|
|
|
|
2010-10-08 03:22:54 +00:00
|
|
|
setNode(res, 0);
|
|
|
|
setNode(clk0, 1);
|
|
|
|
setNode(rdy, 1);
|
|
|
|
setNode(so, 0);
|
|
|
|
setNode(irq, 1);
|
|
|
|
setNode(nmi, 1);
|
2010-09-23 08:06:26 +00:00
|
|
|
|
|
|
|
recalcAllNodes();
|
|
|
|
|
|
|
|
/* hold RESET for 8 cycles */
|
|
|
|
for (int i = 0; i < 16; i++)
|
2010-09-28 17:22:57 +00:00
|
|
|
step();
|
2010-09-23 08:06:26 +00:00
|
|
|
|
|
|
|
/* release RESET */
|
2010-10-08 03:22:54 +00:00
|
|
|
setNode(res, 1);
|
2010-10-05 16:27:33 +00:00
|
|
|
|
|
|
|
cycle = 0;
|
2010-09-22 01:51:38 +00:00
|
|
|
}
|
|
|
|
|
2010-10-06 03:00:20 +00:00
|
|
|
void
|
|
|
|
initAndResetChip()
|
|
|
|
{
|
|
|
|
/* set up data structures for efficient emulation */
|
|
|
|
setupNodesAndTransistors();
|
|
|
|
|
|
|
|
/* set initial state of nodes, transistors, inputs; RESET chip */
|
|
|
|
resetChip();
|
|
|
|
}
|