1
0
mirror of https://github.com/mist64/perfect6502.git synced 2024-06-09 03:29:27 +00:00
This commit is contained in:
Chris Cox 2021-09-29 20:34:38 -07:00 committed by GitHub
commit 3d227038ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 3720 additions and 3774 deletions

3
.gitignore vendored
View File

@ -1,3 +1,5 @@
build
*.xcodeproj
# emacs-style backup files
*~
# patch detritus
@ -6,3 +8,4 @@
# object files
cbmbasic
*.o

View File

@ -1,6 +1,6 @@
OBJS=perfect6502.o netlist_sim.o
OBJS+=cbmbasic/cbmbasic.o cbmbasic/runtime.o cbmbasic/runtime_init.o cbmbasic/plugin.o cbmbasic/console.o cbmbasic/emu.o
OBJS+=measure.o
#OBJS+=measure.o
CFLAGS=-Werror -Wall -O3
CC=cc

View File

@ -1,17 +1,37 @@
#include <stdio.h>
#include "../perfect6502.h"
#include "runtime.h"
#include "runtime_init.h"
#include <time.h>
/*
See https://www.c64-wiki.com/wiki/C64-Commands
10 PRINT 200 * 25.4
20 PRINT 200 / 3.3333
30 END
RUN
*/
#define SHOW_AVG_SPEED 0
int
main()
{
int clk = 0;
void *state = initAndResetChip();
/* set up memory for user program */
init_monitor();
#if SHOW_AVG_SPEED
clock_t end_time;
clock_t start_time = clock();
#endif
/* emulate the 6502! */
for (;;) {
step(state);
@ -19,7 +39,18 @@ main()
if (clk)
handle_monitor(state);
// chipStatus(state);
//if (!(cycle % 1000)) printf("%d\n", cycle);
};
/* chipStatus(state);
*/
#if SHOW_AVG_SPEED
if ( (cycle % 20000) == 0 ) {
end_time = clock();
double time = (end_time - start_time)/ (double)(CLOCKS_PER_SEC);
double speed = cycle / time;
printf("cycle %lu, speed %g steps per second\n", cycle, speed);
}
#endif
} /* end infinite loop */
}

View File

@ -20,11 +20,11 @@ enum {
COLOR_GREY3,
};
void clear_screen();
void up_cursor();
void down_cursor();
void left_cursor();
void right_cursor();
void clear_screen(void);
void up_cursor(void);
void down_cursor(void);
void left_cursor(void);
void right_cursor(void);
void move_cursor(int x, int y);
void get_cursor(int* x, int* y);
void set_color(int c);

View File

@ -16,7 +16,7 @@ static uint16_t PC;
static uint8_t A, X, Y, S, P;
static uint8_t temp_lo, temp_hi;
#define TEMP16 (temp_lo | temp_hi << 8)
#define TEMP16 (uint16_t)( ((uint16_t)temp_lo) | ((uint16_t)temp_hi) << 8)
static uint16_t AB;
static uint8_t DB;
@ -49,7 +49,7 @@ LOAD(uint16_t a)
#define IS_T7 (t & T7)
void
IFETCH()
IFETCH(void)
{
AB = PC;
RW = RW_READ;
@ -57,7 +57,7 @@ IFETCH()
}
void
init()
init(void)
{
t = T1;
ir = 0;
@ -71,7 +71,7 @@ init()
}
void
EOI_INCPC_READPC()
EOI_INCPC_READPC(void)
{
PC++;
t <<= 1;
@ -80,31 +80,31 @@ EOI_INCPC_READPC()
}
void
DB_TO_ADDRLO()
DB_TO_ADDRLO(void)
{
temp_lo = DB;
}
void
DB_TO_ADDRHI()
DB_TO_ADDRHI(void)
{
temp_hi = DB;
}
void
EOI()
EOI(void)
{
t <<= 1;
}
void
EOI_INCPC()
EOI_INCPC(void)
{
PC++;
EOI();
}
void
EOI_INCPC_READADDR()
EOI_INCPC_READADDR(void)
{
EOI_INCPC();
AB = TEMP16;
@ -112,7 +112,7 @@ EOI_INCPC_READADDR()
}
void
EOI_INCPC_WRITEADDR()
EOI_INCPC_WRITEADDR(void)
{
EOI_INCPC();
AB = TEMP16;
@ -120,7 +120,7 @@ EOI_INCPC_WRITEADDR()
}
void
pha()
pha(void)
{
printf("%s",__func__);
if (IS_T2) {
@ -138,7 +138,7 @@ pha()
}
void
plp()
plp(void)
{
printf("%s",__func__);
if (IS_T2) {
@ -162,7 +162,7 @@ plp()
}
void
txs()
txs(void)
{
printf("%s",__func__);
/* T2 */
@ -171,7 +171,7 @@ txs()
}
void
lda_imm()
lda_imm(void)
{
printf("%s",__func__);
/* T2 */
@ -181,7 +181,7 @@ lda_imm()
}
void
ldx_imm()
ldx_imm(void)
{
printf("%s",__func__);
/* T2 */
@ -191,7 +191,7 @@ ldx_imm()
}
void
ldy_imm()
ldy_imm(void)
{
printf("%s",__func__);
/* T2 */
@ -201,7 +201,7 @@ ldy_imm()
}
void
lda_abs()
lda_abs(void)
{
printf("%s",__func__);
if (IS_T2) {
@ -217,7 +217,7 @@ lda_abs()
}
void
sta_abs()
sta_abs(void)
{
printf("%s",__func__);
if (IS_T2) {
@ -235,7 +235,7 @@ sta_abs()
static int cycle = 0;
void
emulate_step()
emulate_step(void)
{
/* memory */
if (RW == RW_READ) {
@ -284,22 +284,22 @@ emulate_step()
}
void
setup_emu()
setup_emu(void)
{
init();
}
void
reset_emu()
reset_emu(void)
{
init();
PC = memory[0xFFFC] | memory[0xFFFD] << 8;
PC = (uint16_t)( memory[0xFFFC] | (((uint16_t)memory[0xFFFD]) << 8) );
printf("PC %x\n", PC);
IFETCH();
}
int
emu_measure_instruction()
emu_measure_instruction(void)
{
for (;;) {

View File

@ -55,8 +55,9 @@
#include "console.h"
static unsigned short
get_chrptr() {
return RAM[0x7A] | RAM[0x7B]<<8;
get_chrptr(void) {
return (unsigned short)(((unsigned short)RAM[0x7A])
| (((unsigned short)RAM[0x7B])<<8));
}
static void
@ -97,19 +98,19 @@ call(unsigned short pc) {
}
static void
check_comma() {
check_comma(void) {
call(0xAEFD);
}
static unsigned short
get_word() {
get_word(void) {
call(0xAD8A);
call(0xB7F7);
return RAM[0x14] | (RAM[0x15]<<8);
return (unsigned short)(((unsigned short)RAM[0x14]) | (((unsigned short)RAM[0x15])<<8));
}
static unsigned char
get_byte() {
get_byte(void) {
call(0xB79E);
return X;
}
@ -120,8 +121,10 @@ get_string(char *s) {
call(0xAD9E);
call(0xB6A3);
for (i = 0; i < A; i++)
s[i] = RAM[(X|(Y<<8))+i];
unsigned short addr = (unsigned short) ( ((unsigned short)X) | (((unsigned short)Y)<<8) );
for (i = 0; i < A; i++) {
s[i] = (char)RAM[addr+i];
}
s[A] = 0;
}
@ -169,7 +172,7 @@ error(unsigned char index) {
* print friendlier strings, or implement "ON ERROR GOTO".
*/
unsigned short
plugin_error() {
plugin_error(void) {
return 0;
}
@ -179,7 +182,7 @@ plugin_error() {
* This gets called whenever we are in direct mode.
*/
unsigned short
plugin_main() {
plugin_main(void) {
return 0;
}
@ -187,7 +190,7 @@ plugin_main() {
* Tokenize BASIC Text
*/
unsigned short
plugin_crnch() {
plugin_crnch(void) {
return 0;
}
@ -195,7 +198,7 @@ plugin_crnch() {
* BASIC Text LIST
*/
unsigned short
plugin_qplop() {
plugin_qplop(void) {
return 0;
}
@ -205,7 +208,7 @@ plugin_qplop() {
* This is used for interpreting statements.
*/
unsigned short
plugin_gone() {
plugin_gone(void) {
set_chrptr(get_chrptr()+1);
for (;;) {
unsigned short chrptr;
@ -282,6 +285,6 @@ plugin_gone() {
* New functions and operators go here.
*/
unsigned short
plugin_eval() {
plugin_eval(void) {
return 0;
}

View File

@ -1,7 +1,7 @@
#define WIN32_LEAN_AND_MEAN
#include <errno.h>
#include <stdlib.h>
#include <windows.h> // FindFirstFile, FindNextFile
//#include <windows.h> // FindFirstFile, FindNextFile
#include "readdir.h"
typedef struct dir_private

View File

@ -162,7 +162,7 @@ init_os(int argc, char **argv) {
if (fgetc(input_file)=='#') {
char c;
do {
c = fgetc(input_file);
c = (char) fgetc(input_file);
} while((c!=13)&&(c!=10));
} else {
fseek(input_file, 0, SEEK_SET);
@ -182,13 +182,13 @@ int plugin = 0;
void
replace_vector(unsigned short address, unsigned short new, unsigned short *old) {
*old = RAM[address] | (RAM[address+1]<<8);
*old = (unsigned short)( (unsigned short)RAM[address] | (((unsigned short)RAM[address+1])<<8) );
RAM[address] = (new)&0xFF;
RAM[address+1] = (new)>>8;
}
void
plugin_on() {
plugin_on(void) {
if (plugin)
return;
@ -203,7 +203,7 @@ plugin_on() {
}
static void
plugin_off() {
plugin_off(void) {
unsigned short dummy;
if (!plugin)
@ -220,13 +220,13 @@ plugin_off() {
}
static void
SETMSG() {
SETMSG(void) {
kernal_msgflag = A;
A = kernal_status;
}
static void
MEMTOP() {
MEMTOP(void) {
#if DEBUG /* CBMBASIC doesn't do this */
if (!C) {
printf("UNIMPL: set top of RAM");
@ -245,7 +245,7 @@ MEMTOP() {
/* MEMBOT */
static void
MEMBOT() {
MEMBOT(void) {
#if DEBUG /* CBMBASIC doesn't do this */
if (!C) {
printf("UNIMPL: set bot of RAM");
@ -258,13 +258,13 @@ MEMBOT() {
/* READST */
static void
READST() {
READST(void) {
A = kernal_status;
}
/* SETLFS */
static void
SETLFS() {
SETLFS(void) {
kernal_lfn = A;
kernal_dev = X;
kernal_sec = Y;
@ -272,14 +272,14 @@ SETLFS() {
/* SETNAM */
static void
SETNAM() {
kernal_filename = X | Y<<8;
SETNAM(void) {
kernal_filename = (unsigned short)( ((unsigned short)X) | (((unsigned short)Y)<<8) );
kernal_filename_len = A;
}
/* OPEN */
static void
OPEN() {
OPEN(void) {
kernal_status = 0;
if (kernal_files[kernal_lfn]) {
C = 1;
@ -305,7 +305,7 @@ OPEN() {
/* CLOSE */
static void
CLOSE() {
CLOSE(void) {
if (!kernal_files[kernal_lfn]) {
C = 1;
A = KERN_ERR_FILE_NOT_OPEN;
@ -318,7 +318,7 @@ CLOSE() {
/* CHKIN */
static void
CHKIN() {
CHKIN(void) {
kernal_status = 0;
if (!kernal_files[X]) {
C = 1;
@ -332,7 +332,7 @@ CHKIN() {
/* CHKOUT */
static void
CHKOUT() {
CHKOUT(void) {
kernal_status = 0;
if (!kernal_files[X]) {
C = 1;
@ -346,7 +346,7 @@ CHKOUT() {
/* CLRCHN */
static void
CLRCHN() {
CLRCHN(void) {
kernal_input = 0;
kernal_output = 0;
}
@ -358,7 +358,7 @@ int fakerun_index = 0;
/* CHRIN */
static void
CHRIN() {
CHRIN(void) {
if ((!interactive) && (readycount==2)) {
exit(0);
}
@ -370,25 +370,25 @@ CHRIN() {
} else {
if (kernal_files_next[kernal_input] == EOF)
kernal_files_next[kernal_input] = fgetc(kernal_files[kernal_input]);
A = kernal_files_next[kernal_input];
A = (unsigned char) kernal_files_next[kernal_input];
kernal_files_next[kernal_input] = fgetc(kernal_files[kernal_input]);
if (kernal_files_next[kernal_input] == EOF)
kernal_status |= KERN_ST_EOF;
}
} else if (!input_file) {
A = getchar(); /* stdin */
A = (unsigned char) getchar(); /* stdin */
if (A=='\n') A = '\r';
} else {
if (fakerun) {
A = run[fakerun_index++];
A = (unsigned char) run[fakerun_index++];
if (fakerun_index==sizeof(run))
input_file = 0; /* switch to stdin */
} else {
A = fgetc(input_file);
A = (unsigned char) fgetc(input_file);
if ((A==255)&&(readycount==1)) {
fakerun = 1;
fakerun_index = 0;
A = run[fakerun_index++];
A = (unsigned char) run[fakerun_index++];
}
if (A=='\n') A = '\r';
}
@ -398,7 +398,7 @@ CHRIN() {
/* CHROUT */
static void
CHROUT() {
CHROUT(void) {
//return;
//exit(1);
#if 0
@ -550,7 +550,7 @@ printf("CHROUT: %d @ %x,%x,%x,%x\n", A, a, b, c, d);
/* LOAD */
static void
LOAD() {
LOAD(void) {
FILE *f;
struct stat st;
unsigned short start;
@ -599,13 +599,13 @@ LOAD() {
while ((dp = readdir(dirp))) {
size_t namlen = strlen(dp->d_name);
stat(dp->d_name, &st);
file_size = (st.st_size + 253)/254; /* convert file size from num of bytes to num of blocks(254 bytes) */
file_size = (int) ((st.st_size + 253)/254); /* convert file size from num of bytes to num of blocks(254 bytes) */
if (file_size>0xFFFF)
file_size = 0xFFFF;
old_memp = memp;
memp += 2;
RAM[memp++] = file_size & 0xFF;
RAM[memp++] = file_size >> 8;
RAM[memp++] = (unsigned char)(file_size & 0xFF);
RAM[memp++] = (unsigned char)(file_size >> 8);
if (file_size<1000) {
RAM[memp++] = ' ';
if (file_size<100) {
@ -621,7 +621,7 @@ LOAD() {
memcpy(&RAM[memp], dp->d_name, namlen);
memp += namlen;
RAM[memp++] = '"';
for (i=namlen; i<16; i++)
for (i=(int)namlen; i<16; i++)
RAM[memp++] = ' ';
RAM[memp++] = ' ';
RAM[memp++] = 'P';
@ -667,10 +667,10 @@ for (i=0; i<255; i++) {
f = fopen((char*)&RAM[kernal_filename], "rb");
if (!f)
goto file_not_found;
start = ((unsigned char)fgetc(f)) | ((unsigned char)fgetc(f))<<8;
start = (unsigned short)( (unsigned char)fgetc(f) | (((unsigned short)fgetc(f))<<8) );
if (!kernal_sec)
start = X | Y<<8;
end = start + fread(&RAM[start], 1, 65536-start, f); /* TODO may overwrite ROM */
start = (unsigned short)(X | (((unsigned short)Y)<<8) );
end = (unsigned short)( start + fread(&RAM[start], 1, 65536-start, f) ); /* TODO may overwrite ROM */
printf("LOADING FROM $%04X to $%04X\n", start, end);
fclose(f);
@ -696,14 +696,14 @@ missing_file_name:
/* SAVE */
static void
SAVE() {
SAVE(void) {
FILE *f;
unsigned char savedbyte;
unsigned short start;
unsigned short end;
start = RAM[A] | RAM[A+1]<<8;
end = X | Y << 8;
start = (unsigned short)( RAM[A] | (((unsigned short)RAM[A+1])<<8) );
end = (unsigned short)( X | (((unsigned short)Y) << 8) );
if (end<start) {
C = 1;
A = KERN_ERR_NONE;
@ -732,7 +732,7 @@ SAVE() {
/* SETTIM */
static void
SETTIM() {
SETTIM(void) {
unsigned long jiffies = Y*65536 + X*256 + A;
unsigned long seconds = jiffies/60;
#ifdef _WIN32
@ -751,9 +751,9 @@ SETTIM() {
localtime_r(&now, &bd);
bd.tm_sec = seconds%60;
bd.tm_min = seconds/60;
bd.tm_hour = seconds/3600;
bd.tm_sec = (int)(seconds%60);
bd.tm_min = (int)(seconds/60);
bd.tm_hour = (int)(seconds/3600);
tv.tv_sec = mktime(&bd);
tv.tv_usec = (jiffies % 60) * (1000000/60);
@ -764,7 +764,7 @@ SETTIM() {
/* RDTIM */
static void
RDTIM() {
RDTIM(void) {
unsigned long jiffies;
#ifdef _WIN32
SYSTEMTIME st;
@ -779,7 +779,7 @@ RDTIM() {
localtime_r(&now, &bd);
gettimeofday(&tv, 0);
jiffies = ((bd.tm_hour*60 + bd.tm_min)*60 + bd.tm_sec)*60 + tv.tv_usec / (1000000/60);
jiffies = (unsigned long)( ((bd.tm_hour*60 + bd.tm_min)*60 + bd.tm_sec)*60 + tv.tv_usec / (1000000/60) );
#endif
Y = (unsigned char)(jiffies/65536);
X = (unsigned char)((jiffies%65536)/256);
@ -789,13 +789,13 @@ RDTIM() {
/* STOP */
static void
STOP() {
STOP(void) {
SETZ(0); /* TODO we don't support the STOP key */
}
/* GETIN */
static void
GETIN() {
GETIN(void) {
if (kernal_input != 0) {
if (feof(kernal_files[kernal_input])) {
kernal_status |= KERN_ST_EOF;
@ -804,7 +804,7 @@ GETIN() {
} else {
if (kernal_files_next[kernal_input] == EOF)
kernal_files_next[kernal_input] = fgetc(kernal_files[kernal_input]);
A = kernal_files_next[kernal_input];
A = (unsigned char) kernal_files_next[kernal_input];
kernal_files_next[kernal_input] = fgetc(kernal_files[kernal_input]);
if (kernal_files_next[kernal_input] == EOF)
kernal_status |= KERN_ST_EOF;
@ -813,11 +813,11 @@ GETIN() {
} else {
#ifdef _WIN32
if (_kbhit())
A = _getch();
A = (unsigned char) _getch();
else
A = 0;
#else
A = getchar();
A = (unsigned char) getchar();
#endif
if (A=='\n') A = '\r';
C = 0;
@ -826,8 +826,8 @@ GETIN() {
/* CLALL */
static void
CLALL() {
int i;
CLALL(void) {
size_t i;
for (i = 0; i < sizeof(kernal_files)/sizeof(kernal_files[0]); ++i) {
if (kernal_files[i]) {
fclose(kernal_files[i]);
@ -838,12 +838,12 @@ CLALL() {
/* PLOT */
static void
PLOT() {
PLOT(void) {
if (C) {
int CX, CY;
get_cursor(&CX, &CY);
Y = CX;
X = CY;
Y = (unsigned char) CX;
X = (unsigned char) CY;
} else {
printf("UNIMPL: set cursor %d %d\n", Y, X);
exit(1);
@ -853,7 +853,7 @@ PLOT() {
/* IOBASE */
static void
IOBASE() {
IOBASE(void) {
#define CIA 0xDC00 /* we could put this anywhere... */
/*
* IOBASE is just used inside RND to get a timer value.
@ -863,19 +863,19 @@ IOBASE() {
*/
int pseudo_timer;
pseudo_timer = rand();
RAM[CIA+4] = pseudo_timer&0xff;
RAM[CIA+5] = pseudo_timer>>8;
RAM[CIA+4] = (unsigned char) (pseudo_timer&0xff);
RAM[CIA+5] = (unsigned char) (pseudo_timer>>8);
pseudo_timer = rand(); /* more entropy! */
RAM[CIA+8] = pseudo_timer&0xff;
RAM[CIA+9] = pseudo_timer>>8;
RAM[CIA+8] = (unsigned char) (pseudo_timer&0xff);
RAM[CIA+9] = (unsigned char) (pseudo_timer>>8);
X = CIA & 0xFF;
Y = CIA >> 8;
}
int
kernal_dispatch() {
kernal_dispatch(void) {
//{ printf("kernal_dispatch $%04X; ", PC); int i; printf("stack (%02X): ", S); for (i=S+1; i<0x100; i++) { printf("%02X ", RAM[0x0100+i]); } printf("\n"); }
unsigned int new_pc;
unsigned short new_pc;
switch(PC) {
case 0x0073: CHRGET(); break;
case 0x0079: CHRGOT(); break;

View File

@ -1 +1 @@
void handle_monitor();
void handle_monitor(void *state);

View File

@ -1,4 +1,5 @@
#include <stdio.h>
#include <stdlib.h>
#include "../perfect6502.h"
/* XXX hook up memory[] with RAM[] in runtime.c */
@ -9,7 +10,7 @@
*
************************************************************/
extern int kernal_dispatch();
extern int kernal_dispatch(void);
/* imported by runtime.c */
unsigned char A, X, Y, S, P;
@ -17,10 +18,14 @@ unsigned short PC;
int N, Z, C;
void
init_monitor()
init_monitor(void)
{
FILE *f;
f = fopen("cbmbasic/cbmbasic.bin", "r");
f = fopen("cbmbasic/cbmbasic.bin", "rb");
if (f == NULL) {
fprintf(stderr,"Could not open cmbasic file\n");
exit(-1);
}
fread(memory + 0xA000, 1, 17591, f);
fclose(f);

View File

@ -1 +1 @@
void init_monitor();
void init_monitor(void);

File diff suppressed because it is too large Load Diff

View File

@ -42,16 +42,24 @@ typedef uint16_t count_t;
*
************************************************************/
#if 1 /* faster on 64 bit CPUs */
#if 1 /* faster on 64 bit CPUs */
typedef unsigned long long bitmap_t;
#define BITMAP_SHIFT 6
#define BITMAP_MASK 63
#define ONE 1ULL
#else
typedef unsigned int bitmap_t;
#elif 0 /* faster on most 32 bit CPUs */
typedef uint32_t bitmap_t;
#define BITMAP_SHIFT 5
#define BITMAP_MASK 31
#define ONE 1UL
#else /* faster in some cases (and compilers) that allow for vectorization */
typedef uint8_t bitmap_t;
#define BITMAP_SHIFT 3
#define BITMAP_MASK 7
#define ONE 1U
#endif
/* list of nodes that need to be recalculated */
@ -83,20 +91,14 @@ typedef struct {
bitmap_t *nodes_pullup;
bitmap_t *nodes_pulldown;
bitmap_t *nodes_value;
nodenum_t **nodes_gates;
c1c2_t *nodes_c1c2s;
count_t *nodes_gatecount;
count_t *nodes_c1c2offset;
nodenum_t *nodes_dependants;
nodenum_t *nodes_left_dependants;
nodenum_t **nodes_dependant;
nodenum_t **nodes_left_dependant;
/* everything that describes a transistor */
nodenum_t *transistors_gate;
nodenum_t *transistors_c1;
nodenum_t *transistors_c2;
bitmap_t *transistors_on;
nodenum_t *nodes_gates;
nodenum_t *node_block;
c1c2_t *nodes_c1c2s;
count_t *nodes_c1c2offset;
nodenum_t *nodes_dependant;
nodenum_t *nodes_left_dependant;
nodenum_t *dependent_block;
/* the nodes we are working with */
nodenum_t *list1;
@ -112,16 +114,17 @@ typedef struct {
count_t groupcount;
bitmap_t *groupbitmap;
enum {
contains_nothing,
contains_hi,
contains_pullup,
contains_pulldown,
contains_vcc,
contains_vss
} group_contains_value;
} state_t;
typedef enum {
contains_nothing = 0,
contains_hi = 1,
contains_pullup = 2,
contains_pulldown = 3,
contains_vcc = 4,
contains_vss = 5
} group_value;
/************************************************************
*
* Main Header Include
@ -262,9 +265,9 @@ listout_clear(state_t *state)
static inline void
listout_add(state_t *state, nodenum_t i)
{
if (!get_bitmap(state->listout_bitmap, i)) {
state->listout.list[state->listout.count++] = i;
if (get_bitmap(state->listout_bitmap, i) == 0) {
set_bitmap(state->listout_bitmap, i, 1);
state->listout.list[state->listout.count++] = i;
}
}
@ -320,8 +323,8 @@ group_count(state_t *state)
*
************************************************************/
static inline void
addNodeToGroup(state_t *state, nodenum_t n)
static inline group_value
addNodeToGroup(state_t *state, nodenum_t n, group_value val)
{
/*
* We need to stop at vss and vcc, otherwise we'll revisit other groups
@ -329,55 +332,61 @@ addNodeToGroup(state_t *state, nodenum_t n)
* the fact that they are connected to vcc or vss.
*/
if (n == state->vss) {
state->group_contains_value = contains_vss;
return;
return contains_vss;
}
if (n == state->vcc) {
if (state->group_contains_value != contains_vss)
state->group_contains_value = contains_vcc;
return;
if (val != contains_vss)
val = contains_vcc;
return val;
}
/* check and see if we already have this node, and if so return */
if (group_contains(state, n))
return;
return val;
group_add(state, n);
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(state, n)) {
state->group_contains_value = contains_pullup;
}
if (state->group_contains_value < contains_hi && get_nodes_value(state, n)) {
state->group_contains_value = contains_hi;
}
/* Give the compiler a hint that all of these can be calculated, and don't need to wait on branches.
This results in a small speedup.
*/
BOOL isPulldown = get_nodes_pulldown(state, n);
BOOL isPullup = get_nodes_pullup(state, n);
BOOL nodeValue = get_nodes_value(state, n);
if (val < contains_pulldown && isPulldown)
val = contains_pulldown;
if (val < contains_pullup && isPullup)
val = contains_pullup;
if (val < contains_hi && nodeValue)
val = contains_hi;
/* state can remain at contains_nothing if the node value is low */
/* revisit all transistors that control this node */
count_t end = state->nodes_c1c2offset[n+1];
for (count_t t = state->nodes_c1c2offset[n]; t < end; t++) {
c1c2_t c = state->nodes_c1c2s[t];
const count_t start = state->nodes_c1c2offset[n];
const count_t end = state->nodes_c1c2offset[n+1];
const c1c2_t *node_c1c2s = state->nodes_c1c2s;
for (count_t t = start; t < end; t++) {
const c1c2_t c = node_c1c2s[t];
/* if the transistor connects c1 and c2... */
if (get_transistors_on(state, c.transistor)) {
addNodeToGroup(state, c.other_node);
val = addNodeToGroup(state, c.other_node, val);
}
}
return val;
}
static inline void
static inline group_value
addAllNodesToGroup(state_t *state, nodenum_t node)
{
group_clear(state);
state->group_contains_value = contains_nothing;
addNodeToGroup(state, node);
return addNodeToGroup(state, node, contains_nothing);
}
static inline BOOL
getGroupValue(state_t *state)
getGroupValue(group_value node_value)
{
switch (state->group_contains_value) {
switch (node_value) {
case contains_vcc:
case contains_pullup:
case contains_hi:
@ -396,10 +405,10 @@ recalcNode(state_t *state, nodenum_t node)
* get all nodes that are connected through
* transistors, starting with this one
*/
addAllNodesToGroup(state, node);
group_value node_value = addAllNodesToGroup(state, node);
/* get the state of the group */
BOOL newv = getGroupValue(state);
BOOL newv = getGroupValue(node_value);
/*
* - set all nodes to the group state
@ -407,22 +416,29 @@ recalcNode(state_t *state, nodenum_t node)
* - collect all nodes behind toggled transistors
* for the next run
*/
for (count_t i = 0; i < group_count(state); i++) {
nodenum_t nn = group_get(state, i);
const count_t grp_count = group_count(state);
for (count_t i = 0; i < grp_count; i++) {
const 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];
const nodenum_t startg = state->nodes_gates[nn];
const nodenum_t endg = state->nodes_gates[nn+1];
for (count_t t = startg; t < endg; t++) {
transnum_t tn = state->node_block[t];
set_transistors_on(state, tn, newv);
}
if (newv) {
for (count_t g = 0; g < state->nodes_left_dependants[nn]; g++) {
listout_add(state, state->nodes_left_dependant[nn][g]);
const nodenum_t dep_offset = state->nodes_left_dependant[nn];
const nodenum_t dep_end = state->nodes_left_dependant[nn+1];
for (count_t g = dep_offset; g < dep_end; g++) {
listout_add(state, state->dependent_block[g]);
}
} else {
for (count_t g = 0; g < state->nodes_dependants[nn]; g++) {
listout_add(state, state->nodes_dependant[nn][g]);
const nodenum_t dep_offset = state->nodes_dependant[nn];
const nodenum_t dep_end = state->nodes_dependant[nn+1];
for (count_t g = dep_offset; g < dep_end; g++) {
listout_add(state, state->dependent_block[g]);
}
}
}
@ -432,7 +448,10 @@ recalcNode(state_t *state, nodenum_t node)
void
recalcNodeList(state_t *state)
{
for (int j = 0; j < 100; j++) { /* loop limiter */
const int max_iterations = 50;
int j;
for (j = 0; j < max_iterations; j++) { /* loop limiter */
/*
* make the secondary list our primary list, use
* the data storage of the primary list as the
@ -452,11 +471,18 @@ recalcNodeList(state_t *state)
* 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(state); i++) {
const count_t list_count = listin_count(state);
for (count_t i = 0; i < list_count; i++) {
nodenum_t n = listin_get(state, i);
recalcNode(state, n);
}
}
if (j == max_iterations) {
fprintf(stderr,"### recalcNodeList max iterations hit, listin.count = %d\n", listin_count(state));
}
/* without this, we'll have a bogus listin on the next step */
listout_clear(state);
}
@ -467,25 +493,31 @@ recalcNodeList(state_t *state)
************************************************************/
static inline void
add_nodes_dependant(state_t *state, nodenum_t a, nodenum_t b)
add_nodes_dependant(state_t *state, nodenum_t a, nodenum_t b, nodenum_t *counts, nodenum_t offset )
{
for (count_t g = 0; g < state->nodes_dependants[a]; g++)
if (state->nodes_dependant[a][g] == b)
return;
/* O(N^2) behavior, but only run during initialization
NOTE - counts are still being set and cannot be calculated from offsets
*/
nodenum_t *dependent_data = state->dependent_block + offset;
const nodenum_t dep_count = counts[a];
for (count_t g = 0; g < dep_count; g++)
if (dependent_data[g] == b)
return;
state->nodes_dependant[a][state->nodes_dependants[a]++] = b;
dependent_data[ counts[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;
}
/* 6502:
3288 transistors, 3239 used in simulation after duplicate removal
1725 entries in node list and used in simulation
c1c2total = 6478
block_gate_size = 3239
block_dep_size = 7260
Working set = 89 KB allocations, 220 KB binary, plus system libs and text buffering
= 604 KB in release build
*/
state_t *
setupNodesAndTransistors(netlist_transdefs *transdefs, BOOL *node_is_pullup, nodenum_t nodes, nodenum_t transistors, nodenum_t vss, nodenum_t vcc)
{
@ -495,120 +527,227 @@ setupNodesAndTransistors(netlist_transdefs *transdefs, BOOL *node_is_pullup, nod
state->transistors = transistors;
state->vss = vss;
state->vcc = vcc;
state->nodes_c1c2offset = calloc(state->nodes + 1, sizeof(*state->nodes_c1c2offset));
state->nodes_pullup = calloc(WORDS_FOR_BITS(state->nodes), sizeof(*state->nodes_pullup));
state->nodes_pulldown = calloc(WORDS_FOR_BITS(state->nodes), sizeof(*state->nodes_pulldown));
state->nodes_value = calloc(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] = calloc(state->nodes, sizeof(**state->nodes_gates));
}
state->nodes_gatecount = calloc(state->nodes, sizeof(*state->nodes_gatecount));
state->nodes_c1c2offset = calloc(state->nodes + 1, sizeof(*state->nodes_c1c2offset));
state->nodes_dependants = calloc(state->nodes, sizeof(*state->nodes_dependants));
state->nodes_left_dependants = calloc(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] = calloc(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] = calloc(state->nodes, sizeof(**state->nodes_left_dependant));
}
state->transistors_gate = calloc(state->transistors, sizeof(*state->transistors_gate));
state->transistors_c1 = calloc(state->transistors, sizeof(*state->transistors_c1));
state->transistors_c2 = calloc(state->transistors, sizeof(*state->transistors_c2));
state->transistors_on = calloc(WORDS_FOR_BITS(state->transistors), sizeof(*state->transistors_on));
state->listout_bitmap = calloc(WORDS_FOR_BITS(state->nodes), sizeof(*state->listout_bitmap));
state->groupbitmap = calloc(WORDS_FOR_BITS(state->nodes), sizeof(*state->groupbitmap));
/* group content depends on active state, not easy to predict actual size needed */
state->group = calloc(state->nodes, sizeof(*state->group));
/* ping pong state buffers */
state->list1 = calloc(state->nodes, sizeof(*state->list1));
state->list2 = calloc(state->nodes, sizeof(*state->list2));
state->listout_bitmap = calloc(WORDS_FOR_BITS(state->nodes), sizeof(*state->listout_bitmap));
state->group = malloc(state->nodes * sizeof(*state->group));
state->groupbitmap = calloc(WORDS_FOR_BITS(state->nodes), sizeof(*state->groupbitmap));
state->listin.list = state->list1;
state->listin.count = 0;
state->listout.list = state->list2;
state->listout.count = 0;
/* these are only used in initialization */
nodenum_t *nodes_dep_count = calloc(state->nodes, sizeof(nodenum_t));
nodenum_t *nodes_left_dep_count = calloc(state->nodes, sizeof(nodenum_t));
count_t *nodes_gatecount = calloc(state->nodes, sizeof(count_t));
nodenum_t *transistors_gate = calloc(state->transistors, sizeof(nodenum_t));
nodenum_t *transistors_c1 = calloc(state->transistors, sizeof(nodenum_t));
nodenum_t *transistors_c2 = calloc(state->transistors, sizeof(nodenum_t));
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;
nodes_gatecount[i] = 0;
}
/* copy transistors into r/w data structure */
count_t j = 0;
/* Copy transistors into r/w data structure and remove duplicates */
count_t transistors_used = 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 */
/* skip duplicate transistors (including ones with reversed c1c2 values)
O(N^2) operation, but only done once at initialization, not a significant time sink */
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))) {
for (count_t j2 = 0; j2 < transistors_used; j2++) {
if (transistors_gate[j2] == gate &&
((transistors_c1[j2] == c1 &&
transistors_c2[j2] == c2) ||
(transistors_c1[j2] == c2 &&
transistors_c2[j2] == c1))) {
found = YES;
break;
}
}
if (!found) {
state->transistors_gate[j] = gate;
state->transistors_c1[j] = c1;
state->transistors_c2[j] = c2;
j++;
transistors_gate[transistors_used] = gate;
transistors_c1[transistors_used] = c1;
transistors_c2[transistors_used] = c2;
transistors_used++;
}
}
state->transistors = j;
state->transistors = transistors_used;
/* cross reference transistors in nodes data structures */
/* start by computing how many c1c2 entries should be created for each node */
count_t *c1c2count = calloc(state->nodes, sizeof(*c1c2count));
count_t c1c2total = 0;
for (i = 0; i < state->transistors; i++) {
nodenum_t gate = state->transistors_gate[i];
state->nodes_gates[gate][state->nodes_gatecount[gate]++] = i;
c1c2count[state->transistors_c1[i]]++;
c1c2count[state->transistors_c2[i]]++;
nodenum_t gate = transistors_gate[i];
nodenum_t c1 = transistors_c1[i];
nodenum_t c2 = transistors_c2[i];
if (gate >= nodes || c1 >= nodes || c2 >= nodes)
fprintf(stderr,"FATAL - bad transistor definition %d\n", i);
nodes_gatecount[gate]++;
c1c2count[c1]++;
c1c2count[c2]++;
c1c2total += 2;
}
/* then sum the counts to find each node's offset into the c1c2 array */
count_t c1c2offset = 0;
for (i = 0; i < state->nodes; i++) {
state->nodes_c1c2offset[i] = c1c2offset;
c1c2offset += c1c2count[i];
}
state->nodes_c1c2offset[i] = c1c2offset;
state->nodes_c1c2offset[i] = c1c2offset; /* fill the end entry, so we can calculate distances/counts */
/* create and fill the nodes_c1c2s array according to these offsets */
state->nodes_c1c2s = calloc(c1c2total, sizeof(*state->nodes_c1c2s));
memset(c1c2count, 0, state->nodes * sizeof(*c1c2count));
memset(c1c2count, 0, state->nodes * sizeof(*c1c2count)); /* zero counts so we can reuse them */
for (i = 0; i < state->transistors; i++) {
nodenum_t c1 = state->transistors_c1[i];
nodenum_t c2 = state->transistors_c2[i];
nodenum_t c1 = transistors_c1[i];
nodenum_t c2 = transistors_c2[i];
state->nodes_c1c2s[state->nodes_c1c2offset[c1] + c1c2count[c1]++] = c1c2(i, c2);
state->nodes_c1c2s[state->nodes_c1c2offset[c2] + c1c2count[c2]++] = c1c2(i, c1);
}
/* this is unused after initialization */
free(c1c2count);
c1c2count = NULL;
/* Sum the counts for total allocation of gates */
size_t block_gate_size = 0;
for (i = 0; i < state->nodes; i++) {
block_gate_size += (size_t) nodes_gatecount[i];
}
/* Allocate the block of gate data all at once */
state->node_block = calloc( block_gate_size, sizeof(*state->nodes_gates) );
/* Assign offsets from our block */
state->nodes_gates = malloc((nodes+1) * sizeof(*state->nodes_gates));
nodenum_t node_index = 0;
for (i = 0; i < state->nodes; i++) {
count_t count = nodes_gatecount[i];
state->nodes_gates[i] = node_index;
node_index += count;
}
state->nodes_gates[state->nodes] = node_index; /* fill the end entry, so we can calculate distances/counts */
/* Cross reference transistors in nodes with smaller data structures */
memset(nodes_gatecount, 0, state->nodes * sizeof(count_t));
for (i = 0; i < state->transistors; i++) {
nodenum_t gate = transistors_gate[i];
nodenum_t *gate_data = state->node_block + state->nodes_gates[gate];
gate_data[ nodes_gatecount[gate]++ ] = 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);
}
}
}
/* See how many dependent node entries we really need.
Must happen after gatecount and nodes_gates assignments!
*/
for (i = 0; i < state->nodes; i++) {
nodes_dep_count[i] = 0;
nodes_left_dep_count[i] = 0;
nodenum_t *gate_data = state->node_block + state->nodes_gates[i];
for (count_t g = 0; g < nodes_gatecount[i]; g++) {
nodenum_t t = gate_data[g];
nodenum_t c1 = transistors_c1[t];
if (c1 != vss && c1 != vcc) {
nodes_dep_count[i]++;
}
nodenum_t c2 = transistors_c2[t];
if (c2 != vss && c2 != vcc) {
nodes_dep_count[i]++;
}
nodes_left_dep_count[i]++;
}
}
/* Sum the counts to find total size of the dependents array */
size_t block_dep_size = 0;
for (i = 0; i < state->nodes; i++) {
block_dep_size += nodes_dep_count[i];
block_dep_size += nodes_left_dep_count[i];
}
/* Allocate the dependents block all at once */
state->dependent_block = calloc( block_dep_size, sizeof(*state->nodes_dependant) );
/* Assign offsets from our block, using only counts needed */
state->nodes_dependant = malloc((nodes+1) * sizeof(*state->nodes_dependant));
nodenum_t dep_index = 0;
for (i = 0; i < state->nodes; i++) {
nodenum_t count = nodes_dep_count[i];
state->nodes_dependant[i] = dep_index;
dep_index += count;
}
state->nodes_dependant[state->nodes] = dep_index; /* fill the end entry, so we can calculate distances/counts */
/* Assign offsets from our block, using only counts needed */
state->nodes_left_dependant = malloc((nodes+1) * sizeof(*state->nodes_left_dependant));
for (i = 0; i < state->nodes; i++) {
nodenum_t count = nodes_left_dep_count[i];
state->nodes_left_dependant[i] = dep_index;
dep_index += count;
}
state->nodes_left_dependant[state->nodes] = dep_index; /* fill the end entry, so we can calculate distances/counts */
/* Copy dependencies into smaller data structures */
for (i = 0; i < state->nodes; i++) {
nodes_dep_count[i] = 0;
nodes_left_dep_count[i] = 0;
nodenum_t *gate_data = state->node_block + state->nodes_gates[i];
for (count_t g = 0; g < nodes_gatecount[i]; g++) {
nodenum_t t = gate_data[g];
nodenum_t c1 = transistors_c1[t];
if (c1 != vss && c1 != vcc) {
add_nodes_dependant(state, i, c1, nodes_dep_count, state->nodes_dependant[i]);
}
nodenum_t c2 = transistors_c2[t];
if (c2 != vss && c2 != vcc) {
add_nodes_dependant(state, i, c2, nodes_dep_count, state->nodes_dependant[i]);
}
if (c1 != vss && c1 != vcc) {
add_nodes_dependant(state, i, c1, nodes_left_dep_count, state->nodes_left_dependant[i]);
} else {
add_nodes_dependant(state, i, c2, nodes_left_dep_count, state->nodes_left_dependant[i]);
}
}
}
/* these are unused after initialization */
free(nodes_dep_count);
nodes_dep_count = NULL;
free(nodes_left_dep_count);
nodes_left_dep_count = NULL;
free(nodes_gatecount);
nodes_gatecount = NULL;
free(transistors_gate);
transistors_gate = NULL;
free(transistors_c1);
transistors_c1 = NULL;
free(transistors_c2);
transistors_c2 = NULL;
#if 0 /* unnecessary - RESET will stabilize the network anyway */
/* all nodes are down */
@ -617,7 +756,7 @@ setupNodesAndTransistors(netlist_transdefs *transdefs, BOOL *node_is_pullup, nod
}
/* all transistors are off */
for (transnum_t tn = 0; tn < state->transistors; tn++)
set_transistors_on(state, tn, NO);
set_transistors_on(state, tn, NO);
#endif
return state;
@ -629,26 +768,11 @@ destroyNodesAndTransistors(state_t *state)
free(state->nodes_pullup);
free(state->nodes_pulldown);
free(state->nodes_value);
for (count_t i = 0; i < state->nodes; i++) {
free(state->nodes_gates[i]);
}
free(state->nodes_gates);
free(state->node_block);
free(state->nodes_c1c2s);
free(state->nodes_gatecount);
free(state->nodes_c1c2offset);
free(state->nodes_dependants);
free(state->nodes_left_dependants);
for (count_t i = 0; i < state->nodes; i++) {
free(state->nodes_dependant[i]);
}
free(state->nodes_dependant);
for (count_t i = 0; i < state->nodes; i++) {
free(state->nodes_left_dependant[i]);
}
free(state->nodes_left_dependant);
free(state->transistors_gate);
free(state->transistors_c1);
free(state->transistors_c2);
free(state->dependent_block);
free(state->transistors_on);
free(state->list1);
free(state->list2);
@ -662,7 +786,7 @@ void
stabilizeChip(state_t *state)
{
for (count_t i = 0; i < state->nodes; i++)
listout_add(state, i);
listout_add(state, i);
recalcNodeList(state);
}
@ -676,11 +800,11 @@ stabilizeChip(state_t *state)
void
setNode(state_t *state, nodenum_t nn, BOOL s)
{
set_nodes_pullup(state, nn, s);
set_nodes_pulldown(state, nn, !s);
listout_add(state, nn);
set_nodes_pullup(state, nn, s);
set_nodes_pulldown(state, nn, !s);
listout_add(state, nn);
recalcNodeList(state);
recalcNodeList(state);
}
BOOL
@ -698,7 +822,7 @@ isNodeHigh(state_t *state, nodenum_t nn)
unsigned int
readNodes(state_t *state, int count, nodenum_t *nodelist)
{
int result = 0;
unsigned int result = 0;
for (int i = count - 1; i >= 0; i--) {
result <<= 1;
result |= isNodeHigh(state, nodelist[i]);
@ -710,5 +834,5 @@ void
writeNodes(state_t *state, int count, nodenum_t *nodelist, int v)
{
for (int i = 0; i < 8; i++, v >>= 1)
setNode(state, nodelist[i], v & 1);
setNode(state, nodelist[i], v & 1);
}

View File

@ -35,13 +35,13 @@
uint16_t
readAddressBus(void *state)
{
return readNodes(state, 16, (nodenum_t[]){ ab0, ab1, ab2, ab3, ab4, ab5, ab6, ab7, ab8, ab9, ab10, ab11, ab12, ab13, ab14, ab15 });
return (uint16_t)readNodes(state, 16, (nodenum_t[]){ ab0, ab1, ab2, ab3, ab4, ab5, ab6, ab7, ab8, ab9, ab10, ab11, ab12, ab13, ab14, ab15 });
}
uint8_t
readDataBus(void *state)
{
return readNodes(state, 8, (nodenum_t[]){ db0, db1, db2, db3, db4, db5, db6, db7 });
return (uint8_t)readNodes(state, 8, (nodenum_t[]){ db0, db1, db2, db3, db4, db5, db6, db7 });
}
void
@ -59,55 +59,55 @@ readRW(void *state)
uint8_t
readA(void *state)
{
return readNodes(state, 8, (nodenum_t[]){ a0,a1,a2,a3,a4,a5,a6,a7 });
return (uint8_t)readNodes(state, 8, (nodenum_t[]){ a0,a1,a2,a3,a4,a5,a6,a7 });
}
uint8_t
readX(void *state)
{
return readNodes(state, 8, (nodenum_t[]){ x0,x1,x2,x3,x4,x5,x6,x7 });
return (uint8_t)readNodes(state, 8, (nodenum_t[]){ x0,x1,x2,x3,x4,x5,x6,x7 });
}
uint8_t
readY(void *state)
{
return readNodes(state, 8, (nodenum_t[]){ y0,y1,y2,y3,y4,y5,y6,y7 });
return (uint8_t)readNodes(state, 8, (nodenum_t[]){ y0,y1,y2,y3,y4,y5,y6,y7 });
}
uint8_t
readP(void *state)
{
return readNodes(state, 8, (nodenum_t[]){ p0,p1,p2,p3,p4,p5,p6,p7 });
return (uint8_t)readNodes(state, 8, (nodenum_t[]){ p0,p1,p2,p3,p4,p5,p6,p7 });
}
uint8_t
readIR(void *state)
{
return readNodes(state, 8, (nodenum_t[]){ notir0,notir1,notir2,notir3,notir4,notir5,notir6,notir7 }) ^ 0xFF;
return (uint8_t)readNodes(state, 8, (nodenum_t[]){ notir0,notir1,notir2,notir3,notir4,notir5,notir6,notir7 }) ^ 0xFF;
}
uint8_t
readSP(void *state)
{
return readNodes(state, 8, (nodenum_t[]){ s0,s1,s2,s3,s4,s5,s6,s7 });
return (uint8_t)readNodes(state, 8, (nodenum_t[]){ s0,s1,s2,s3,s4,s5,s6,s7 });
}
uint8_t
readPCL(void *state)
{
return readNodes(state, 8, (nodenum_t[]){ pcl0,pcl1,pcl2,pcl3,pcl4,pcl5,pcl6,pcl7 });
return (uint8_t)readNodes(state, 8, (nodenum_t[]){ pcl0,pcl1,pcl2,pcl3,pcl4,pcl5,pcl6,pcl7 });
}
uint8_t
readPCH(void *state)
{
return readNodes(state, 8, (nodenum_t[]){ pch0,pch1,pch2,pch3,pch4,pch5,pch6,pch7 });
return (uint8_t)readNodes(state, 8, (nodenum_t[]){ pch0,pch1,pch2,pch3,pch4,pch5,pch6,pch7 });
}
uint16_t
readPC(void *state)
{
return (readPCH(state) << 8) | readPCL(state);
return (uint16_t)((uint16_t)readPCH(state) << 8) | ((uint16_t)readPCL(state));
}
/************************************************************
@ -145,7 +145,7 @@ handleMemory(void *state)
*
************************************************************/
unsigned int cycle;
unsigned long cycle;
void
step(void *state)
@ -164,7 +164,7 @@ step(void *state)
}
void *
initAndResetChip()
initAndResetChip(void)
{
/* set up data structures for efficient emulation */
nodenum_t nodes = sizeof(netlist_6502_node_is_pullup)/sizeof(*netlist_6502_node_is_pullup);
@ -218,7 +218,7 @@ chipStatus(void *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",
printf("halfcyc:%ld phi0:%d AB:%04X D:%02X RnW:%d PC:%04X A:%02X X:%02X Y:%02X SP:%02X P:%02X IR:%02X",
cycle,
clk,
a,

View File

@ -2,7 +2,7 @@
#define state_t void
#endif
extern state_t *initAndResetChip();
extern state_t *initAndResetChip(void);
extern void destroyChip(state_t *state);
extern void step(state_t *state);
extern void chipStatus(state_t *state);
@ -19,5 +19,5 @@ extern unsigned char readDataBus(state_t *state);
extern unsigned char readIR(state_t *state);
extern unsigned char memory[65536];
extern unsigned int cycle;
extern unsigned int transistors;
extern unsigned long cycle;
//extern unsigned int transistors;

10
types.h
View File

@ -3,16 +3,16 @@
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int BOOL;
typedef unsigned char BOOL;
typedef uint16_t nodenum_t;
typedef struct {
int gate;
int c1;
int c2;
nodenum_t gate;
nodenum_t c1;
nodenum_t c2;
} netlist_transdefs;
#define YES 1
#define NO 0
#endif
#endif