cleanup
This commit is contained in:
parent
c93f229339
commit
44cde717a1
1
Makefile
1
Makefile
|
@ -1,7 +1,6 @@
|
|||
OBJS=perfect6502.o
|
||||
OBJS+=cbmbasic.o runtime.o runtime_init.o plugin.o console.o emu.o
|
||||
#OBJS+=measure.o
|
||||
#OBJS+=broken_transistors.o runtime.o runtime_init.o plugin.o console.o emu.o
|
||||
CFLAGS=-Werror -Wall -O3
|
||||
CC=clang
|
||||
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
#include "perfect6502.h"
|
||||
|
||||
extern void init_monitor();
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int BOOL;
|
||||
|
||||
#define YES 1
|
||||
#define NO 0
|
||||
|
||||
#define MAX_CYCLES 33000
|
||||
BOOL log_rw[MAX_CYCLES];
|
||||
uint16_t log_ab[MAX_CYCLES];
|
||||
uint8_t log_db[MAX_CYCLES];
|
||||
int
|
||||
main()
|
||||
{
|
||||
initAndResetChip();
|
||||
printf("%d\n", transistors);
|
||||
int stransistors = transistors;
|
||||
for (int run = -1; run < stransistors; run ++) {
|
||||
#if 0
|
||||
/* skip a few runs! */
|
||||
if (run == 0)
|
||||
run = 180;
|
||||
#endif
|
||||
|
||||
if (run != -1) {
|
||||
printf("testing transistor %d: ", run);
|
||||
broken_transistor = run;
|
||||
}
|
||||
|
||||
bzero(memory, 65536);
|
||||
init_monitor();
|
||||
resetChip();
|
||||
BOOL fail = NO;
|
||||
for (int c = 0; c < MAX_CYCLES; c++) {
|
||||
step();
|
||||
if (run == -1) {
|
||||
log_rw[c] = cycle & 1;
|
||||
log_ab[c] = readAddressBus();
|
||||
log_db[c] = readDataBus();
|
||||
} else {
|
||||
if (log_rw[c] != (cycle & 1)) {
|
||||
printf("FAIL, RW %d instead of %d @ %d\n", cycle & 1, log_rw[c], c);
|
||||
fail = YES;
|
||||
break;
|
||||
}
|
||||
if (log_ab[c] != readAddressBus()) {
|
||||
printf("FAIL, AB 0x%04x instead of 0x%04x @ %d\n", readAddressBus(), log_ab[c], c);
|
||||
fail = YES;
|
||||
break;
|
||||
}
|
||||
if (log_db[c] != readDataBus()) {
|
||||
printf("FAIL, DB 0x%02x instead of 0x%02x @ %d\n", readDataBus(), log_db[c], c);
|
||||
fail = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (run != -1 && !fail)
|
||||
printf("PASS\n");
|
||||
}
|
||||
}
|
345
perfect6502.c
345
perfect6502.c
|
@ -461,6 +461,160 @@ recalcNodeList(state_t *state)
|
|||
listout_clear(state);
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
*
|
||||
* Initialization
|
||||
*
|
||||
************************************************************/
|
||||
|
||||
static inline void
|
||||
add_nodes_dependant(state_t *state, nodenum_t a, nodenum_t b)
|
||||
{
|
||||
for (count_t g = 0; g < state->nodes_dependants[a]; g++)
|
||||
if (state->nodes_dependant[a][g] == b)
|
||||
return;
|
||||
|
||||
state->nodes_dependant[a][state->nodes_dependants[a]++] = b;
|
||||
}
|
||||
|
||||
static inline void
|
||||
add_nodes_left_dependant(state_t *state, nodenum_t a, nodenum_t b)
|
||||
{
|
||||
for (count_t g = 0; g < state->nodes_left_dependants[a]; g++)
|
||||
if (state->nodes_left_dependant[a][g] == b)
|
||||
return;
|
||||
|
||||
state->nodes_left_dependant[a][state->nodes_left_dependants[a]++] = b;
|
||||
}
|
||||
|
||||
static state_t *
|
||||
setupNodesAndTransistors(netlist_transdefs *transdefs, BOOL *node_is_pullup, nodenum_t nodes, nodenum_t transistors)
|
||||
{
|
||||
/* allocate state */
|
||||
state_t *state = malloc(sizeof(state_t));
|
||||
state->nodes = nodes;
|
||||
state->transistors = transistors;
|
||||
state->nodes_pullup = malloc(WORDS_FOR_BITS(state->nodes) * sizeof(*state->nodes_pullup));
|
||||
state->nodes_pulldown = malloc(WORDS_FOR_BITS(state->nodes) * sizeof(*state->nodes_pulldown));
|
||||
state->nodes_value = malloc(WORDS_FOR_BITS(state->nodes) * sizeof(*state->nodes_value));
|
||||
state->nodes_gates = malloc(state->nodes * sizeof(*state->nodes_gates));
|
||||
for (count_t i = 0; i < state->nodes; i++) {
|
||||
state->nodes_gates[i] = malloc(state->nodes * sizeof(**state->nodes_gates));
|
||||
}
|
||||
state->nodes_c1c2s = malloc(state->nodes * sizeof(*state->nodes_c1c2s));
|
||||
for (count_t i = 0; i < state->nodes; i++) {
|
||||
state->nodes_c1c2s[i] = malloc(2 * state->nodes * sizeof(**state->nodes_c1c2s));
|
||||
}
|
||||
state->nodes_gatecount = malloc(state->nodes * sizeof(*state->nodes_gatecount));
|
||||
state->nodes_c1c2count = malloc(state->nodes * sizeof(*state->nodes_c1c2count));
|
||||
state->nodes_dependants = malloc(state->nodes * sizeof(*state->nodes_dependants));
|
||||
state->nodes_left_dependants = malloc(state->nodes * sizeof(*state->nodes_left_dependants));
|
||||
state->nodes_dependant = malloc(state->nodes * sizeof(*state->nodes_dependant));
|
||||
for (count_t i = 0; i < state->nodes; i++) {
|
||||
state->nodes_dependant[i] = malloc(state->nodes * sizeof(**state->nodes_dependant));
|
||||
}
|
||||
state->nodes_left_dependant = malloc(state->nodes * sizeof(*state->nodes_left_dependant));
|
||||
for (count_t i = 0; i < state->nodes; i++) {
|
||||
state->nodes_left_dependant[i] = malloc(state->nodes * sizeof(**state->nodes_left_dependant));
|
||||
}
|
||||
state->transistors_gate = malloc(state->transistors * sizeof(*state->transistors_gate));
|
||||
state->transistors_c1 = malloc(state->transistors * sizeof(*state->transistors_c1));
|
||||
state->transistors_c2 = malloc(state->transistors * sizeof(*state->transistors_c2));
|
||||
state->transistors_on = malloc(WORDS_FOR_BITS(state->transistors) * sizeof(*state->transistors_on));
|
||||
state->list1 = malloc(state->nodes * sizeof(*state->list1));
|
||||
state->list2 = malloc(state->nodes * sizeof(*state->list2));
|
||||
state->listout_bitmap = malloc(WORDS_FOR_BITS(state->nodes) * sizeof(*state->listout_bitmap));
|
||||
state->group = malloc(state->nodes * sizeof(*state->group));
|
||||
state->groupbitmap = malloc(WORDS_FOR_BITS(state->nodes) * sizeof(*state->groupbitmap));
|
||||
state->listin.list = state->list1;
|
||||
state->listout.list = state->list2;
|
||||
|
||||
count_t i;
|
||||
/* copy nodes into r/w data structure */
|
||||
for (i = 0; i < state->nodes; i++) {
|
||||
set_nodes_pullup(state, i, node_is_pullup[i]);
|
||||
state->nodes_gatecount[i] = 0;
|
||||
state->nodes_c1c2count[i] = 0;
|
||||
}
|
||||
/* copy transistors into r/w data structure */
|
||||
count_t j = 0;
|
||||
for (i = 0; i < state->transistors; i++) {
|
||||
nodenum_t gate = transdefs[i].gate;
|
||||
nodenum_t c1 = transdefs[i].c1;
|
||||
nodenum_t c2 = transdefs[i].c2;
|
||||
/* skip duplicate transistors */
|
||||
BOOL found = NO;
|
||||
for (count_t j2 = 0; j2 < j; j2++) {
|
||||
if (state->transistors_gate[j2] == gate &&
|
||||
((state->transistors_c1[j2] == c1 &&
|
||||
state->transistors_c2[j2] == c2) ||
|
||||
(state->transistors_c1[j2] == c2 &&
|
||||
state->transistors_c2[j2] == c1))) {
|
||||
found = YES;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
state->transistors_gate[j] = gate;
|
||||
state->transistors_c1[j] = c1;
|
||||
state->transistors_c2[j] = c2;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
state->transistors = j;
|
||||
|
||||
/* cross reference transistors in nodes data structures */
|
||||
for (i = 0; i < state->transistors; i++) {
|
||||
nodenum_t gate = state->transistors_gate[i];
|
||||
nodenum_t c1 = state->transistors_c1[i];
|
||||
nodenum_t c2 = state->transistors_c2[i];
|
||||
state->nodes_gates[gate][state->nodes_gatecount[gate]++] = i;
|
||||
state->nodes_c1c2s[c1][state->nodes_c1c2count[c1]++] = i;
|
||||
state->nodes_c1c2s[c2][state->nodes_c1c2count[c2]++] = i;
|
||||
}
|
||||
|
||||
for (i = 0; i < state->nodes; i++) {
|
||||
state->nodes_dependants[i] = 0;
|
||||
state->nodes_left_dependants[i] = 0;
|
||||
for (count_t g = 0; g < state->nodes_gatecount[i]; g++) {
|
||||
transnum_t t = state->nodes_gates[i][g];
|
||||
nodenum_t c1 = state->transistors_c1[t];
|
||||
if (c1 != vss && c1 != vcc) {
|
||||
add_nodes_dependant(state, i, c1);
|
||||
}
|
||||
nodenum_t c2 = state->transistors_c2[t];
|
||||
if (c2 != vss && c2 != vcc) {
|
||||
add_nodes_dependant(state, i, c2);
|
||||
}
|
||||
if (c1 != vss && c1 != vcc) {
|
||||
add_nodes_left_dependant(state, i, c1);
|
||||
} else {
|
||||
add_nodes_left_dependant(state, i, c2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 /* unnecessary - RESET will stabilize the network anyway */
|
||||
/* all nodes are down */
|
||||
for (nodenum_t nn = 0; nn < state->nodes; nn++) {
|
||||
set_nodes_value(state, nn, 0);
|
||||
}
|
||||
/* all transistors are off */
|
||||
for (transnum_t tn = 0; tn < state->transistors; tn++)
|
||||
set_transistors_on(state, tn, NO);
|
||||
#endif
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void
|
||||
stabilizeChip(state_t *state)
|
||||
{
|
||||
for (count_t i = 0; i < state->nodes; i++)
|
||||
listout_add(state, i);
|
||||
|
||||
recalcNodeList(state);
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
*
|
||||
* Node State
|
||||
|
@ -682,177 +836,6 @@ step(state_t *state)
|
|||
cycle++;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
*
|
||||
* Initialization
|
||||
*
|
||||
************************************************************/
|
||||
|
||||
static inline void
|
||||
add_nodes_dependant(state_t *state, nodenum_t a, nodenum_t b)
|
||||
{
|
||||
for (count_t g = 0; g < state->nodes_dependants[a]; g++)
|
||||
if (state->nodes_dependant[a][g] == b)
|
||||
return;
|
||||
|
||||
state->nodes_dependant[a][state->nodes_dependants[a]++] = b;
|
||||
}
|
||||
|
||||
static inline void
|
||||
add_nodes_left_dependant(state_t *state, nodenum_t a, nodenum_t b)
|
||||
{
|
||||
for (count_t g = 0; g < state->nodes_left_dependants[a]; g++)
|
||||
if (state->nodes_left_dependant[a][g] == b)
|
||||
return;
|
||||
|
||||
state->nodes_left_dependant[a][state->nodes_left_dependants[a]++] = b;
|
||||
}
|
||||
|
||||
static state_t *
|
||||
setupNodesAndTransistors(netlist_transdefs *transdefs, BOOL *node_is_pullup, nodenum_t nodes, nodenum_t transistors)
|
||||
{
|
||||
/* allocate state */
|
||||
state_t *state = malloc(sizeof(state_t));
|
||||
state->nodes = nodes;
|
||||
state->transistors = transistors;
|
||||
state->nodes_pullup = malloc(WORDS_FOR_BITS(state->nodes) * sizeof(*state->nodes_pullup));
|
||||
state->nodes_pulldown = malloc(WORDS_FOR_BITS(state->nodes) * sizeof(*state->nodes_pulldown));
|
||||
state->nodes_value = malloc(WORDS_FOR_BITS(state->nodes) * sizeof(*state->nodes_value));
|
||||
state->nodes_gates = malloc(state->nodes * sizeof(*state->nodes_gates));
|
||||
for (count_t i = 0; i < state->nodes; i++) {
|
||||
state->nodes_gates[i] = malloc(state->nodes * sizeof(**state->nodes_gates));
|
||||
}
|
||||
state->nodes_c1c2s = malloc(state->nodes * sizeof(*state->nodes_c1c2s));
|
||||
for (count_t i = 0; i < state->nodes; i++) {
|
||||
state->nodes_c1c2s[i] = malloc(2 * state->nodes * sizeof(**state->nodes_c1c2s));
|
||||
}
|
||||
state->nodes_gatecount = malloc(state->nodes * sizeof(*state->nodes_gatecount));
|
||||
state->nodes_c1c2count = malloc(state->nodes * sizeof(*state->nodes_c1c2count));
|
||||
state->nodes_dependants = malloc(state->nodes * sizeof(*state->nodes_dependants));
|
||||
state->nodes_left_dependants = malloc(state->nodes * sizeof(*state->nodes_left_dependants));
|
||||
state->nodes_dependant = malloc(state->nodes * sizeof(*state->nodes_dependant));
|
||||
for (count_t i = 0; i < state->nodes; i++) {
|
||||
state->nodes_dependant[i] = malloc(state->nodes * sizeof(**state->nodes_dependant));
|
||||
}
|
||||
state->nodes_left_dependant = malloc(state->nodes * sizeof(*state->nodes_left_dependant));
|
||||
for (count_t i = 0; i < state->nodes; i++) {
|
||||
state->nodes_left_dependant[i] = malloc(state->nodes * sizeof(**state->nodes_left_dependant));
|
||||
}
|
||||
state->transistors_gate = malloc(state->transistors * sizeof(*state->transistors_gate));
|
||||
state->transistors_c1 = malloc(state->transistors * sizeof(*state->transistors_c1));
|
||||
state->transistors_c2 = malloc(state->transistors * sizeof(*state->transistors_c2));
|
||||
state->transistors_on = malloc(WORDS_FOR_BITS(state->transistors) * sizeof(*state->transistors_on));
|
||||
state->list1 = malloc(state->nodes * sizeof(*state->list1));
|
||||
state->list2 = malloc(state->nodes * sizeof(*state->list2));
|
||||
state->listout_bitmap = malloc(WORDS_FOR_BITS(state->nodes) * sizeof(*state->listout_bitmap));
|
||||
state->group = malloc(state->nodes * sizeof(*state->group));
|
||||
state->groupbitmap = malloc(WORDS_FOR_BITS(state->nodes) * sizeof(*state->groupbitmap));
|
||||
state->listin.list = state->list1;
|
||||
state->listout.list = state->list2;
|
||||
|
||||
count_t i;
|
||||
/* copy nodes into r/w data structure */
|
||||
for (i = 0; i < state->nodes; i++) {
|
||||
set_nodes_pullup(state, i, node_is_pullup[i]);
|
||||
state->nodes_gatecount[i] = 0;
|
||||
state->nodes_c1c2count[i] = 0;
|
||||
}
|
||||
/* copy transistors into r/w data structure */
|
||||
count_t j = 0;
|
||||
for (i = 0; i < state->transistors; i++) {
|
||||
nodenum_t gate = transdefs[i].gate;
|
||||
nodenum_t c1 = transdefs[i].c1;
|
||||
nodenum_t c2 = transdefs[i].c2;
|
||||
/* skip duplicate transistors */
|
||||
BOOL found = NO;
|
||||
for (count_t j2 = 0; j2 < j; j2++) {
|
||||
if (state->transistors_gate[j2] == gate &&
|
||||
((state->transistors_c1[j2] == c1 &&
|
||||
state->transistors_c2[j2] == c2) ||
|
||||
(state->transistors_c1[j2] == c2 &&
|
||||
state->transistors_c2[j2] == c1))) {
|
||||
found = YES;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
state->transistors_gate[j] = gate;
|
||||
state->transistors_c1[j] = c1;
|
||||
state->transistors_c2[j] = c2;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
state->transistors = j;
|
||||
|
||||
/* cross reference transistors in nodes data structures */
|
||||
for (i = 0; i < state->transistors; i++) {
|
||||
nodenum_t gate = state->transistors_gate[i];
|
||||
nodenum_t c1 = state->transistors_c1[i];
|
||||
nodenum_t c2 = state->transistors_c2[i];
|
||||
state->nodes_gates[gate][state->nodes_gatecount[gate]++] = i;
|
||||
state->nodes_c1c2s[c1][state->nodes_c1c2count[c1]++] = i;
|
||||
state->nodes_c1c2s[c2][state->nodes_c1c2count[c2]++] = i;
|
||||
}
|
||||
|
||||
for (i = 0; i < state->nodes; i++) {
|
||||
state->nodes_dependants[i] = 0;
|
||||
state->nodes_left_dependants[i] = 0;
|
||||
for (count_t g = 0; g < state->nodes_gatecount[i]; g++) {
|
||||
transnum_t t = state->nodes_gates[i][g];
|
||||
nodenum_t c1 = state->transistors_c1[t];
|
||||
if (c1 != vss && c1 != vcc) {
|
||||
add_nodes_dependant(state, i, c1);
|
||||
}
|
||||
nodenum_t c2 = state->transistors_c2[t];
|
||||
if (c2 != vss && c2 != vcc) {
|
||||
add_nodes_dependant(state, i, c2);
|
||||
}
|
||||
if (c1 != vss && c1 != vcc) {
|
||||
add_nodes_left_dependant(state, i, c1);
|
||||
} else {
|
||||
add_nodes_left_dependant(state, i, c2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void
|
||||
resetChip(state_t *state)
|
||||
{
|
||||
#if 0 /* unnecessary - RESET will stabilize the network anyway */
|
||||
/* all nodes are down */
|
||||
for (nodenum_t nn = 0; nn < state->nodes; nn++) {
|
||||
set_nodes_value(state, nn, 0);
|
||||
}
|
||||
/* all transistors are off */
|
||||
for (transnum_t tn = 0; tn < state->transistors; tn++)
|
||||
set_transistors_on(state, tn, NO);
|
||||
#endif
|
||||
|
||||
setNode(state, res, 0);
|
||||
setNode(state, clk0, 1);
|
||||
setNode(state, rdy, 1);
|
||||
setNode(state, so, 0);
|
||||
setNode(state, irq, 1);
|
||||
setNode(state, nmi, 1);
|
||||
|
||||
for (count_t i = 0; i < state->nodes; i++)
|
||||
listout_add(state, i);
|
||||
|
||||
recalcNodeList(state);
|
||||
|
||||
/* hold RESET for 8 cycles */
|
||||
for (int i = 0; i < 16; i++)
|
||||
step(state);
|
||||
|
||||
/* release RESET */
|
||||
setNode(state, res, 1);
|
||||
recalcNodeList(state);
|
||||
|
||||
cycle = 0;
|
||||
}
|
||||
|
||||
state_t *
|
||||
initAndResetChip()
|
||||
{
|
||||
|
@ -864,8 +847,24 @@ initAndResetChip()
|
|||
nodes,
|
||||
transistors);
|
||||
|
||||
/* set initial state of nodes, transistors, inputs; RESET chip */
|
||||
resetChip(state);
|
||||
setNode(state, res, 0);
|
||||
setNode(state, clk0, 1);
|
||||
setNode(state, rdy, 1);
|
||||
setNode(state, so, 0);
|
||||
setNode(state, irq, 1);
|
||||
setNode(state, nmi, 1);
|
||||
|
||||
stabilizeChip(state);
|
||||
|
||||
/* hold RESET for 8 cycles */
|
||||
for (int i = 0; i < 16; i++)
|
||||
step(state);
|
||||
|
||||
/* release RESET */
|
||||
setNode(state, res, 1);
|
||||
recalcNodeList(state);
|
||||
|
||||
cycle = 0;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#endif
|
||||
|
||||
extern state_t *initAndResetChip();
|
||||
extern void resetChip(state_t *state);
|
||||
extern void step(state_t *state);
|
||||
extern void chipStatus(state_t *state);
|
||||
extern unsigned short readPC(state_t *state);
|
||||
|
@ -14,7 +13,7 @@ extern unsigned char readSP(state_t *state);
|
|||
extern unsigned char readP(state_t *state);
|
||||
extern unsigned int readRW(state_t *state);
|
||||
extern unsigned short readAddressBus(state_t *state);
|
||||
//extern void writeDataBus(unsigned char);
|
||||
extern void writeDataBus(state_t *state, unsigned char);
|
||||
extern unsigned char readDataBus(state_t *state);
|
||||
extern unsigned char readIR(state_t *state);
|
||||
|
||||
|
|
Loading…
Reference in New Issue