mirror of
https://github.com/mist64/perfect6502.git
synced 2025-01-14 13:30:02 +00:00
The state pointer is no longer global, but passed down to every function.
...and surprisingly, it's not any slower. if anything, it's 1% faster.
This commit is contained in:
parent
b8af4edbbe
commit
c4f7cfb449
@ -7,19 +7,19 @@ main()
|
||||
{
|
||||
int clk = 0;
|
||||
|
||||
initAndResetChip();
|
||||
void *state = initAndResetChip();
|
||||
|
||||
/* set up memory for user program */
|
||||
init_monitor();
|
||||
|
||||
/* emulate the 6502! */
|
||||
for (;;) {
|
||||
step();
|
||||
step(state);
|
||||
clk = !clk;
|
||||
if (clk)
|
||||
handle_monitor();
|
||||
handle_monitor(state);
|
||||
|
||||
// chipStatus();
|
||||
// chipStatus(state);
|
||||
//if (!(cycle % 1000)) printf("%d\n", cycle);
|
||||
};
|
||||
}
|
||||
|
400
perfect6502.c
400
perfect6502.c
@ -32,8 +32,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "perfect6502.h"
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int BOOL;
|
||||
@ -167,7 +165,9 @@ typedef struct {
|
||||
} group_contains_value;
|
||||
} state_t;
|
||||
|
||||
state_t state;
|
||||
#define INCLUDED_FROM_PERFECT6502_C
|
||||
#include "perfect6502.h"
|
||||
#undef INCLUDED_FROM_PERFECT6502_C
|
||||
|
||||
/*
|
||||
* The "value" propertiy of VCC and GND is never evaluated in the code,
|
||||
@ -175,39 +175,39 @@ state_t state;
|
||||
*/
|
||||
|
||||
static inline void
|
||||
set_nodes_pullup(transnum_t t, BOOL s)
|
||||
set_nodes_pullup(state_t *state, transnum_t t, BOOL s)
|
||||
{
|
||||
set_bitmap(state.nodes_pullup, t, s);
|
||||
set_bitmap(state->nodes_pullup, t, s);
|
||||
}
|
||||
|
||||
static inline BOOL
|
||||
get_nodes_pullup(transnum_t t)
|
||||
get_nodes_pullup(state_t *state, transnum_t t)
|
||||
{
|
||||
return get_bitmap(state.nodes_pullup, t);
|
||||
return get_bitmap(state->nodes_pullup, t);
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_nodes_pulldown(transnum_t t, BOOL s)
|
||||
set_nodes_pulldown(state_t *state, transnum_t t, BOOL s)
|
||||
{
|
||||
set_bitmap(state.nodes_pulldown, t, s);
|
||||
set_bitmap(state->nodes_pulldown, t, s);
|
||||
}
|
||||
|
||||
static inline BOOL
|
||||
get_nodes_pulldown(transnum_t t)
|
||||
get_nodes_pulldown(state_t *state, transnum_t t)
|
||||
{
|
||||
return get_bitmap(state.nodes_pulldown, t);
|
||||
return get_bitmap(state->nodes_pulldown, t);
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_nodes_value(transnum_t t, BOOL s)
|
||||
set_nodes_value(state_t *state, transnum_t t, BOOL s)
|
||||
{
|
||||
set_bitmap(state.nodes_value, t, s);
|
||||
set_bitmap(state->nodes_value, t, s);
|
||||
}
|
||||
|
||||
static inline BOOL
|
||||
get_nodes_value(transnum_t t)
|
||||
get_nodes_value(state_t *state, transnum_t t)
|
||||
{
|
||||
return get_bitmap(state.nodes_value, t);
|
||||
return get_bitmap(state->nodes_value, t);
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
@ -221,19 +221,19 @@ unsigned int broken_transistor = (unsigned int)-1;
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
set_transistors_on(transnum_t t, BOOL s)
|
||||
set_transistors_on(state_t *state, transnum_t t, BOOL s)
|
||||
{
|
||||
#ifdef BROKEN_TRANSISTORS
|
||||
if (t == broken_transistor)
|
||||
return;
|
||||
#endif
|
||||
set_bitmap(state.transistors_on, t, s);
|
||||
set_bitmap(state->transistors_on, t, s);
|
||||
}
|
||||
|
||||
static inline BOOL
|
||||
get_transistors_on(transnum_t t)
|
||||
get_transistors_on(state_t *state, transnum_t t)
|
||||
{
|
||||
return get_bitmap(state.transistors_on, t);
|
||||
return get_bitmap(state->transistors_on, t);
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
@ -243,38 +243,38 @@ get_transistors_on(transnum_t t)
|
||||
************************************************************/
|
||||
|
||||
static inline nodenum_t
|
||||
listin_get(count_t i)
|
||||
listin_get(state_t *state, count_t i)
|
||||
{
|
||||
return state.listin.list[i];
|
||||
return state->listin.list[i];
|
||||
}
|
||||
|
||||
static inline count_t
|
||||
listin_count()
|
||||
listin_count(state_t *state)
|
||||
{
|
||||
return state.listin.count;
|
||||
return state->listin.count;
|
||||
}
|
||||
|
||||
static inline void
|
||||
lists_switch()
|
||||
lists_switch(state_t *state)
|
||||
{
|
||||
list_t tmp = state.listin;
|
||||
state.listin = state.listout;
|
||||
state.listout = tmp;
|
||||
list_t tmp = state->listin;
|
||||
state->listin = state->listout;
|
||||
state->listout = tmp;
|
||||
}
|
||||
|
||||
static inline void
|
||||
listout_clear()
|
||||
listout_clear(state_t *state)
|
||||
{
|
||||
state.listout.count = 0;
|
||||
bitmap_clear(state.listout_bitmap, NODES);
|
||||
state->listout.count = 0;
|
||||
bitmap_clear(state->listout_bitmap, NODES);
|
||||
}
|
||||
|
||||
static inline void
|
||||
listout_add(nodenum_t i)
|
||||
listout_add(state_t *state, nodenum_t i)
|
||||
{
|
||||
if (!get_bitmap(state.listout_bitmap, i)) {
|
||||
state.listout.list[state.listout.count++] = i;
|
||||
set_bitmap(state.listout_bitmap, i, 1);
|
||||
if (!get_bitmap(state->listout_bitmap, i)) {
|
||||
state->listout.list[state->listout.count++] = i;
|
||||
set_bitmap(state->listout_bitmap, i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -293,35 +293,35 @@ listout_add(nodenum_t i)
|
||||
*/
|
||||
|
||||
static inline void
|
||||
group_clear()
|
||||
group_clear(state_t *state)
|
||||
{
|
||||
state.groupcount = 0;
|
||||
bitmap_clear(state.groupbitmap, NODES);
|
||||
state->groupcount = 0;
|
||||
bitmap_clear(state->groupbitmap, NODES);
|
||||
}
|
||||
|
||||
static inline void
|
||||
group_add(nodenum_t i)
|
||||
group_add(state_t *state, nodenum_t i)
|
||||
{
|
||||
state.group[state.groupcount++] = i;
|
||||
set_bitmap(state.groupbitmap, i, 1);
|
||||
state->group[state->groupcount++] = i;
|
||||
set_bitmap(state->groupbitmap, i, 1);
|
||||
}
|
||||
|
||||
static inline nodenum_t
|
||||
group_get(count_t n)
|
||||
group_get(state_t *state, count_t n)
|
||||
{
|
||||
return state.group[n];
|
||||
return state->group[n];
|
||||
}
|
||||
|
||||
static inline BOOL
|
||||
group_contains(nodenum_t el)
|
||||
group_contains(state_t *state, nodenum_t el)
|
||||
{
|
||||
return get_bitmap(state.groupbitmap, el);
|
||||
return get_bitmap(state->groupbitmap, el);
|
||||
}
|
||||
|
||||
static inline count_t
|
||||
group_count()
|
||||
group_count(state_t *state)
|
||||
{
|
||||
return state.groupcount;
|
||||
return state->groupcount;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
@ -331,7 +331,7 @@ group_count()
|
||||
************************************************************/
|
||||
|
||||
static void
|
||||
addNodeToGroup(nodenum_t n)
|
||||
addNodeToGroup(state_t *state, nodenum_t n)
|
||||
{
|
||||
/*
|
||||
* We need to stop at vss and vcc, otherwise we'll revisit other groups
|
||||
@ -339,58 +339,58 @@ addNodeToGroup(nodenum_t n)
|
||||
* the fact that they are connected to vcc or vss.
|
||||
*/
|
||||
if (n == vss) {
|
||||
state.group_contains_value = contains_vss;
|
||||
state->group_contains_value = contains_vss;
|
||||
return;
|
||||
}
|
||||
if (n == vcc) {
|
||||
if (state.group_contains_value != contains_vss)
|
||||
state.group_contains_value = contains_vcc;
|
||||
if (state->group_contains_value != contains_vss)
|
||||
state->group_contains_value = contains_vcc;
|
||||
return;
|
||||
}
|
||||
|
||||
if (group_contains(n))
|
||||
if (group_contains(state, n))
|
||||
return;
|
||||
|
||||
group_add(n);
|
||||
group_add(state, n);
|
||||
|
||||
if (state.group_contains_value < contains_pulldown && get_nodes_pulldown(n)) {
|
||||
state.group_contains_value = contains_pulldown;
|
||||
if (state->group_contains_value < contains_pulldown && get_nodes_pulldown(state, n)) {
|
||||
state->group_contains_value = contains_pulldown;
|
||||
}
|
||||
if (state.group_contains_value < contains_pullup && get_nodes_pullup(n)) {
|
||||
state.group_contains_value = contains_pullup;
|
||||
if (state->group_contains_value < contains_pullup && get_nodes_pullup(state, n)) {
|
||||
state->group_contains_value = contains_pullup;
|
||||
}
|
||||
if (state.group_contains_value < contains_hi && get_nodes_value(n)) {
|
||||
state.group_contains_value = contains_hi;
|
||||
if (state->group_contains_value < contains_hi && get_nodes_value(state, n)) {
|
||||
state->group_contains_value = contains_hi;
|
||||
}
|
||||
|
||||
/* revisit all transistors that control this node */
|
||||
for (count_t t = 0; t < state.nodes_c1c2count[n]; t++) {
|
||||
transnum_t tn = state.nodes_c1c2s[n][t];
|
||||
for (count_t t = 0; t < state->nodes_c1c2count[n]; t++) {
|
||||
transnum_t tn = state->nodes_c1c2s[n][t];
|
||||
/* if the transistor connects c1 and c2... */
|
||||
if (get_transistors_on(tn)) {
|
||||
if (get_transistors_on(state, tn)) {
|
||||
/* if original node was connected to c1, continue with c2 */
|
||||
if (state.transistors_c1[tn] == n)
|
||||
addNodeToGroup(state.transistors_c2[tn]);
|
||||
if (state->transistors_c1[tn] == n)
|
||||
addNodeToGroup(state, state->transistors_c2[tn]);
|
||||
else
|
||||
addNodeToGroup(state.transistors_c1[tn]);
|
||||
addNodeToGroup(state, state->transistors_c1[tn]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
addAllNodesToGroup(node)
|
||||
addAllNodesToGroup(state_t *state, nodenum_t node)
|
||||
{
|
||||
group_clear();
|
||||
group_clear(state);
|
||||
|
||||
state.group_contains_value = contains_nothing;
|
||||
state->group_contains_value = contains_nothing;
|
||||
|
||||
addNodeToGroup(node);
|
||||
addNodeToGroup(state, node);
|
||||
}
|
||||
|
||||
static inline BOOL
|
||||
getGroupValue()
|
||||
getGroupValue(state_t *state)
|
||||
{
|
||||
switch (state.group_contains_value) {
|
||||
switch (state->group_contains_value) {
|
||||
case contains_vcc:
|
||||
case contains_pullup:
|
||||
case contains_hi:
|
||||
@ -403,16 +403,16 @@ getGroupValue()
|
||||
}
|
||||
|
||||
void
|
||||
recalcNode(nodenum_t node)
|
||||
recalcNode(state_t *state, nodenum_t node)
|
||||
{
|
||||
/*
|
||||
* get all nodes that are connected through
|
||||
* transistors, starting with this one
|
||||
*/
|
||||
addAllNodesToGroup(node);
|
||||
addAllNodesToGroup(state, node);
|
||||
|
||||
/* get the state of the group */
|
||||
BOOL newv = getGroupValue();
|
||||
BOOL newv = getGroupValue(state);
|
||||
|
||||
/*
|
||||
* - set all nodes to the group state
|
||||
@ -420,22 +420,22 @@ recalcNode(nodenum_t node)
|
||||
* - collect all nodes behind toggled transistors
|
||||
* for the next run
|
||||
*/
|
||||
for (count_t i = 0; i < group_count(); i++) {
|
||||
nodenum_t nn = group_get(i);
|
||||
if (get_nodes_value(nn) != newv) {
|
||||
set_nodes_value(nn, newv);
|
||||
for (count_t t = 0; t < state.nodes_gatecount[nn]; t++) {
|
||||
transnum_t tn = state.nodes_gates[nn][t];
|
||||
set_transistors_on(tn, newv);
|
||||
for (count_t i = 0; i < group_count(state); i++) {
|
||||
nodenum_t nn = group_get(state, i);
|
||||
if (get_nodes_value(state, nn) != newv) {
|
||||
set_nodes_value(state, nn, newv);
|
||||
for (count_t t = 0; t < state->nodes_gatecount[nn]; t++) {
|
||||
transnum_t tn = state->nodes_gates[nn][t];
|
||||
set_transistors_on(state, tn, newv);
|
||||
}
|
||||
|
||||
if (newv) {
|
||||
for (count_t g = 0; g < state.nodes_left_dependants[nn]; g++) {
|
||||
listout_add(state.nodes_left_dependant[nn][g]);
|
||||
for (count_t g = 0; g < state->nodes_left_dependants[nn]; g++) {
|
||||
listout_add(state, state->nodes_left_dependant[nn][g]);
|
||||
}
|
||||
} else {
|
||||
for (count_t g = 0; g < state.nodes_dependants[nn]; g++) {
|
||||
listout_add(state.nodes_dependant[nn][g]);
|
||||
for (count_t g = 0; g < state->nodes_dependants[nn]; g++) {
|
||||
listout_add(state, state->nodes_dependant[nn][g]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -443,7 +443,7 @@ recalcNode(nodenum_t node)
|
||||
}
|
||||
|
||||
void
|
||||
recalcNodeList()
|
||||
recalcNodeList(state_t *state)
|
||||
{
|
||||
for (int j = 0; j < 100; j++) { /* loop limiter */
|
||||
/*
|
||||
@ -451,12 +451,12 @@ recalcNodeList()
|
||||
* the data storage of the primary list as the
|
||||
* secondary list
|
||||
*/
|
||||
lists_switch();
|
||||
lists_switch(state);
|
||||
|
||||
if (!listin_count())
|
||||
if (!listin_count(state))
|
||||
break;
|
||||
|
||||
listout_clear();
|
||||
listout_clear(state);
|
||||
|
||||
/*
|
||||
* for all nodes, follow their paths through
|
||||
@ -465,12 +465,12 @@ recalcNodeList()
|
||||
* all transistors controlled by this path, collecting
|
||||
* all nodes that changed because of it for the next run
|
||||
*/
|
||||
for (count_t i = 0; i < listin_count(); i++) {
|
||||
nodenum_t n = listin_get(i);
|
||||
recalcNode(n);
|
||||
for (count_t i = 0; i < listin_count(state); i++) {
|
||||
nodenum_t n = listin_get(state, i);
|
||||
recalcNode(state, n);
|
||||
}
|
||||
}
|
||||
listout_clear();
|
||||
listout_clear(state);
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
@ -480,20 +480,20 @@ recalcNodeList()
|
||||
************************************************************/
|
||||
|
||||
static inline void
|
||||
setNode(nodenum_t nn, BOOL state)
|
||||
setNode(state_t *state, nodenum_t nn, BOOL s)
|
||||
{
|
||||
BOOL oldstate = get_nodes_pullup(nn);
|
||||
if (state != oldstate) {
|
||||
set_nodes_pullup(nn, state);
|
||||
set_nodes_pulldown(nn, !state);
|
||||
listout_add(nn);
|
||||
BOOL oldstate = get_nodes_pullup(state, nn);
|
||||
if (s != oldstate) {
|
||||
set_nodes_pullup(state, nn, s);
|
||||
set_nodes_pulldown(state, nn, !s);
|
||||
listout_add(state, nn);
|
||||
}
|
||||
}
|
||||
|
||||
static inline BOOL
|
||||
isNodeHigh(nodenum_t nn)
|
||||
isNodeHigh(state_t *state, nodenum_t nn)
|
||||
{
|
||||
return get_nodes_value(nn);
|
||||
return get_nodes_value(state, nn);
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
@ -502,86 +502,86 @@ isNodeHigh(nodenum_t nn)
|
||||
*
|
||||
************************************************************/
|
||||
|
||||
#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))
|
||||
#define read8(state, n0,n1,n2,n3,n4,n5,n6,n7) ((uint8_t)(isNodeHigh(state, n0) << 0) | (isNodeHigh(state, n1) << 1) | (isNodeHigh(state, n2) << 2) | (isNodeHigh(state, n3) << 3) | (isNodeHigh(state, n4) << 4) | (isNodeHigh(state, n5) << 5) | (isNodeHigh(state, n6) << 6) | (isNodeHigh(state, n7) << 7))
|
||||
|
||||
uint16_t
|
||||
readAddressBus()
|
||||
readAddressBus(state_t *state)
|
||||
{
|
||||
return read8(ab0,ab1,ab2,ab3,ab4,ab5,ab6,ab7) | (read8(ab8,ab9,ab10,ab11,ab12,ab13,ab14,ab15) << 8);
|
||||
return read8(state, ab0,ab1,ab2,ab3,ab4,ab5,ab6,ab7) | (read8(state, ab8,ab9,ab10,ab11,ab12,ab13,ab14,ab15) << 8);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
readDataBus()
|
||||
readDataBus(state_t *state)
|
||||
{
|
||||
return read8(db0,db1,db2,db3,db4,db5,db6,db7);
|
||||
return read8(state, db0,db1,db2,db3,db4,db5,db6,db7);
|
||||
}
|
||||
|
||||
void
|
||||
writeDataBus(uint8_t d)
|
||||
writeDataBus(state_t *state, uint8_t d)
|
||||
{
|
||||
static const nodenum_t dbnodes[8] = { db0, db1, db2, db3, db4, db5, db6, db7 };
|
||||
for (int i = 0; i < 8; i++, d>>=1)
|
||||
setNode(dbnodes[i], d & 1);
|
||||
setNode(state, dbnodes[i], d & 1);
|
||||
}
|
||||
|
||||
BOOL
|
||||
readRW()
|
||||
readRW(state_t *state)
|
||||
{
|
||||
return isNodeHigh(rw);
|
||||
return isNodeHigh(state, rw);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
readA()
|
||||
readA(state_t *state)
|
||||
{
|
||||
return read8(a0,a1,a2,a3,a4,a5,a6,a7);
|
||||
return read8(state, a0,a1,a2,a3,a4,a5,a6,a7);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
readX()
|
||||
readX(state_t *state)
|
||||
{
|
||||
return read8(x0,x1,x2,x3,x4,x5,x6,x7);
|
||||
return read8(state, x0,x1,x2,x3,x4,x5,x6,x7);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
readY()
|
||||
readY(state_t *state)
|
||||
{
|
||||
return read8(y0,y1,y2,y3,y4,y5,y6,y7);
|
||||
return read8(state, y0,y1,y2,y3,y4,y5,y6,y7);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
readP()
|
||||
readP(state_t *state)
|
||||
{
|
||||
return read8(p0,p1,p2,p3,p4,p5,p6,p7);
|
||||
return read8(state, p0,p1,p2,p3,p4,p5,p6,p7);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
readIR()
|
||||
readIR(state_t *state)
|
||||
{
|
||||
return read8(notir0,notir1,notir2,notir3,notir4,notir5,notir6,notir7) ^ 0xFF;
|
||||
return read8(state, notir0,notir1,notir2,notir3,notir4,notir5,notir6,notir7) ^ 0xFF;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
readSP()
|
||||
readSP(state_t *state)
|
||||
{
|
||||
return read8(s0,s1,s2,s3,s4,s5,s6,s7);
|
||||
return read8(state, s0,s1,s2,s3,s4,s5,s6,s7);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
readPCL()
|
||||
readPCL(state_t *state)
|
||||
{
|
||||
return read8(pcl0,pcl1,pcl2,pcl3,pcl4,pcl5,pcl6,pcl7);
|
||||
return read8(state, pcl0,pcl1,pcl2,pcl3,pcl4,pcl5,pcl6,pcl7);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
readPCH()
|
||||
readPCH(state_t *state)
|
||||
{
|
||||
return read8(pch0,pch1,pch2,pch3,pch4,pch5,pch6,pch7);
|
||||
return read8(state, pch0,pch1,pch2,pch3,pch4,pch5,pch6,pch7);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
readPC()
|
||||
readPC(state_t *state)
|
||||
{
|
||||
return (readPCH() << 8) | readPCL();
|
||||
return (readPCH(state) << 8) | readPCL(state);
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
@ -593,12 +593,12 @@ readPC()
|
||||
unsigned int cycle;
|
||||
|
||||
void
|
||||
chipStatus()
|
||||
chipStatus(state_t *state)
|
||||
{
|
||||
BOOL clk = isNodeHigh(clk0);
|
||||
uint16_t a = readAddressBus();
|
||||
uint8_t d = readDataBus();
|
||||
BOOL r_w = isNodeHigh(rw);
|
||||
BOOL clk = isNodeHigh(state, clk0);
|
||||
uint16_t a = readAddressBus(state);
|
||||
uint8_t d = readDataBus(state);
|
||||
BOOL r_w = isNodeHigh(state, rw);
|
||||
|
||||
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",
|
||||
cycle,
|
||||
@ -606,13 +606,13 @@ chipStatus()
|
||||
a,
|
||||
d,
|
||||
r_w,
|
||||
readPC(),
|
||||
readA(),
|
||||
readX(),
|
||||
readY(),
|
||||
readSP(),
|
||||
readP(),
|
||||
readIR());
|
||||
readPC(state),
|
||||
readA(state),
|
||||
readX(state),
|
||||
readY(state),
|
||||
readSP(state),
|
||||
readP(state),
|
||||
readIR(state));
|
||||
|
||||
if (clk) {
|
||||
if (r_w)
|
||||
@ -643,12 +643,12 @@ mWrite(uint16_t a, uint8_t d)
|
||||
}
|
||||
|
||||
static inline void
|
||||
handleMemory()
|
||||
handleMemory(state_t *state)
|
||||
{
|
||||
if (isNodeHigh(rw))
|
||||
writeDataBus(mRead(readAddressBus()));
|
||||
if (isNodeHigh(state, rw))
|
||||
writeDataBus(state, mRead(readAddressBus(state)));
|
||||
else
|
||||
mWrite(readAddressBus(), readDataBus());
|
||||
mWrite(readAddressBus(state), readDataBus(state));
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
@ -658,17 +658,17 @@ handleMemory()
|
||||
************************************************************/
|
||||
|
||||
void
|
||||
step()
|
||||
step(state_t *state)
|
||||
{
|
||||
BOOL clk = isNodeHigh(clk0);
|
||||
BOOL clk = isNodeHigh(state, clk0);
|
||||
|
||||
/* invert clock */
|
||||
setNode(clk0, !clk);
|
||||
recalcNodeList();
|
||||
setNode(state, clk0, !clk);
|
||||
recalcNodeList(state);
|
||||
|
||||
/* handle memory reads and writes */
|
||||
if (!clk)
|
||||
handleMemory();
|
||||
handleMemory(state);
|
||||
|
||||
cycle++;
|
||||
}
|
||||
@ -682,34 +682,34 @@ step()
|
||||
unsigned int transistors;
|
||||
|
||||
static inline void
|
||||
add_nodes_dependant(nodenum_t a, nodenum_t b)
|
||||
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)
|
||||
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;
|
||||
state->nodes_dependant[a][state->nodes_dependants[a]++] = b;
|
||||
}
|
||||
|
||||
static inline void
|
||||
add_nodes_left_dependant(nodenum_t a, nodenum_t b)
|
||||
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)
|
||||
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;
|
||||
state->nodes_left_dependant[a][state->nodes_left_dependants[a]++] = b;
|
||||
}
|
||||
|
||||
void
|
||||
setupNodesAndTransistors()
|
||||
setupNodesAndTransistors(state_t *state)
|
||||
{
|
||||
count_t i;
|
||||
/* copy nodes into r/w data structure */
|
||||
for (i = 0; i < NODES; i++) {
|
||||
set_nodes_pullup(i, segdefs[i] == 1);
|
||||
state.nodes_gatecount[i] = 0;
|
||||
state.nodes_c1c2count[i] = 0;
|
||||
set_nodes_pullup(state, i, segdefs[i] == 1);
|
||||
state->nodes_gatecount[i] = 0;
|
||||
state->nodes_c1c2count[i] = 0;
|
||||
}
|
||||
/* copy transistors into r/w data structure */
|
||||
count_t j = 0;
|
||||
@ -732,9 +732,9 @@ setupNodesAndTransistors()
|
||||
}
|
||||
#endif
|
||||
if (!found) {
|
||||
state.transistors_gate[j] = gate;
|
||||
state.transistors_c1[j] = c1;
|
||||
state.transistors_c2[j] = c2;
|
||||
state->transistors_gate[j] = gate;
|
||||
state->transistors_c1[j] = c1;
|
||||
state->transistors_c2[j] = c2;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
@ -745,79 +745,83 @@ setupNodesAndTransistors()
|
||||
|
||||
/* cross reference transistors in nodes data structures */
|
||||
for (i = 0; i < 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;
|
||||
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 < 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];
|
||||
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(i, c1);
|
||||
add_nodes_dependant(state, i, c1);
|
||||
}
|
||||
nodenum_t c2 = state.transistors_c2[t];
|
||||
nodenum_t c2 = state->transistors_c2[t];
|
||||
if (c2 != vss && c2 != vcc) {
|
||||
add_nodes_dependant(i, c2);
|
||||
add_nodes_dependant(state, i, c2);
|
||||
}
|
||||
if (c1 != vss && c1 != vcc) {
|
||||
add_nodes_left_dependant(i, c1);
|
||||
add_nodes_left_dependant(state, i, c1);
|
||||
} else {
|
||||
add_nodes_left_dependant(i, c2);
|
||||
add_nodes_left_dependant(state, i, c2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
resetChip()
|
||||
resetChip(state_t *state)
|
||||
{
|
||||
/* all nodes are down */
|
||||
for (nodenum_t nn = 0; nn < NODES; nn++) {
|
||||
set_nodes_value(nn, 0);
|
||||
set_nodes_value(state, nn, 0);
|
||||
}
|
||||
/* all transistors are off */
|
||||
for (transnum_t tn = 0; tn < TRANSISTORS; tn++)
|
||||
set_transistors_on(tn, NO);
|
||||
set_transistors_on(state, tn, NO);
|
||||
|
||||
setNode(res, 0);
|
||||
setNode(clk0, 1);
|
||||
setNode(rdy, 1);
|
||||
setNode(so, 0);
|
||||
setNode(irq, 1);
|
||||
setNode(nmi, 1);
|
||||
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 < NODES; i++)
|
||||
listout_add(i);
|
||||
listout_add(state, i);
|
||||
|
||||
recalcNodeList();
|
||||
recalcNodeList(state);
|
||||
|
||||
/* hold RESET for 8 cycles */
|
||||
for (int i = 0; i < 16; i++)
|
||||
step();
|
||||
step(state);
|
||||
|
||||
/* release RESET */
|
||||
setNode(res, 1);
|
||||
recalcNodeList();
|
||||
setNode(state, res, 1);
|
||||
recalcNodeList(state);
|
||||
|
||||
cycle = 0;
|
||||
}
|
||||
|
||||
void
|
||||
state_t *
|
||||
initAndResetChip()
|
||||
{
|
||||
state.listin.list = state.list1;
|
||||
state.listout.list = state.list2;
|
||||
state_t *state = malloc(sizeof(state_t));
|
||||
|
||||
state->listin.list = state->list1;
|
||||
state->listout.list = state->list2;
|
||||
|
||||
/* set up data structures for efficient emulation */
|
||||
setupNodesAndTransistors();
|
||||
setupNodesAndTransistors(state);
|
||||
|
||||
/* set initial state of nodes, transistors, inputs; RESET chip */
|
||||
resetChip();
|
||||
resetChip(state);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
@ -1,18 +1,22 @@
|
||||
extern void initAndResetChip();
|
||||
extern void resetChip();
|
||||
extern void step();
|
||||
extern void chipStatus();
|
||||
extern unsigned short readPC();
|
||||
extern unsigned char readA();
|
||||
extern unsigned char readX();
|
||||
extern unsigned char readY();
|
||||
extern unsigned char readSP();
|
||||
extern unsigned char readP();
|
||||
extern unsigned int readRW();
|
||||
extern unsigned short readAddressBus();
|
||||
extern void writeDataBus(unsigned char);
|
||||
extern unsigned char readDataBus();
|
||||
extern unsigned char readIR();
|
||||
#ifndef INCLUDED_FROM_PERFECT6502_C
|
||||
#define state_t void
|
||||
#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);
|
||||
extern unsigned char readA(state_t *state);
|
||||
extern unsigned char readX(state_t *state);
|
||||
extern unsigned char readY(state_t *state);
|
||||
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 unsigned char readDataBus(state_t *state);
|
||||
extern unsigned char readIR(state_t *state);
|
||||
|
||||
extern unsigned char memory[65536];
|
||||
extern unsigned int cycle;
|
||||
|
@ -50,17 +50,17 @@ init_monitor()
|
||||
}
|
||||
|
||||
void
|
||||
handle_monitor()
|
||||
handle_monitor(void *state)
|
||||
{
|
||||
PC = readPC();
|
||||
PC = readPC(state);
|
||||
|
||||
if (PC >= 0xFF90 && ((PC - 0xFF90) % 3 == 0)) {
|
||||
/* get register status out of 6502 */
|
||||
A = readA();
|
||||
X = readX();
|
||||
Y = readY();
|
||||
S = readSP();
|
||||
P = readP();
|
||||
A = readA(state);
|
||||
X = readX(state);
|
||||
Y = readY(state);
|
||||
S = readSP(state);
|
||||
P = readP(state);
|
||||
N = P >> 7;
|
||||
Z = (P >> 1) & 1;
|
||||
C = P & 1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user