#include "opcode.h"
#include <assert.h>
#include <ctype.h>
#include <string.h>
#include <pthread.h>
#define bench 0
#define debug 0
#define IO 1
#define keypoll 0
#if bench
#include <sys/time.h>
#else
#include <curses.h>
#endif
#define THREADS 1
#define BENCH_INST 100000000 << THREADS-1
#define CTRL_ADDR 0xC000
#define TX_ADDR 0xC001
#define RX_ADDR 0xC002
#define STEP_ADDR 0xC010
#define CURSES_BACKSPACE 0x7F
#define setflag(flag, bit) ((flag)) ? (cpu->ps |= (bit << (thread << 3))) : (cpu->ps &= ~(bit << (thread << 3)))
#define getflag(bit) (cpu->ps & (bit << (thread << 3)))
uint64_t clk[THREADS];
uint64_t tclk;
uint64_t inst[THREADS];
uint64_t inss;
uint8_t threads_done = 0;
uint8_t kbd_rdy = 0;
uint8_t wai = 0;
uint8_t step = 0;
uint8_t irq = 0;
#if !bench
WINDOW *scr;
#endif
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t main_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_cond_t main_cond = PTHREAD_COND_INITIALIZER;
struct suxthr {
struct sux sx;
uint8_t th;
};
#if bench
double ipc;
struct timeval str[THREADS], en[THREADS];
#endif
void *run(void *args) {
struct suxthr *thr = (void *)args;
struct sux *cpu = &thr->sx;
uint8_t thread = thr->th;
uint64_t address = 0;
uint64_t tmpaddr = 0;
uint8_t prefix = 0;
uint8_t opcode = 0;
uint8_t end = 0;
uint8_t stksize;
uint64_t sum = 0;
uint64_t value = 0;
uint64_t reg = 0;
uint64_t iclk = 0;
uint64_t ins = 0;
uint64_t sign = 0;
uint8_t addrsize;
uint8_t rs;
uint8_t regsize;
uint8_t tmp;
uint8_t tmp2;
char *s = malloc(2048);
#if !bench
uint8_t lines = (6*thread)+2;
uint8_t bcd[4];
uint8_t idx = 3, iscol = 0;
int x = 0, y = 0;
uint8_t esc = 0;
#endif
uint16_t tv = 0xFF50;
#if bench
gettimeofday(&str[thread], 0);
#endif
#if debug && !bench
uint8_t scr_row = 0xFF, scr_col = 0xFF;
uint8_t updt = 0;
#if keypoll
pthread_mutex_lock(&mutex);
#endif
werase(scr);
#if keypoll
pthread_mutex_unlock(&mutex);
#endif
#endif
while (!end) {
address = 0;
if (wai) {
for (int8_t i = 56; i >= 0; i-=8) {
if (i)
addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread]-1 >> i;
else
addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread]-1 & 0xFF;
cpu->sp[thread]--;
}
addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->ps >> 8*thread;
cpu->sp[thread]--;
setflag(1, I);
cpu->pc[thread] = (uint64_t)addr[0xFFA0]
| (uint64_t)addr[0xFFA1] << 8
| (uint64_t)addr[0xFFA2] << 16
| (uint64_t)addr[0xFFA3] << 24
| (uint64_t)addr[0xFFA4] << 32
| (uint64_t)addr[0xFFA5] << 40
| (uint64_t)addr[0xFFA6] << 48
| (uint64_t)addr[0xFFA7] << 56;
wai = 0;
kbd_rdy &= (uint8_t)~(1 << thread);
}
prefix = addr[cpu->pc[thread]];
if ((prefix & 0x03) == 0x03)
cpu->pc[thread]++;
else
prefix = 0;
opcode = addr[cpu->pc[thread]];
#if debug && !bench
if (lines > 24*(thread+1)) {
lines = (24*thread)+2;
}
#if keypoll
pthread_mutex_lock(&mutex);
#endif
wmove(scr, lines, 0);
wclrtoeol(scr);
wprintw(scr,
"pc: $%08llX"
", a: $%016llX"
", b: $%016llX"
", x: $%016llX"
", y: $%016llX"
, cpu->pc[thread]
, cpu->a[thread]
, cpu->b[thread]
, cpu->x[thread]
, cpu->y[thread]);
wprintw(scr,
", sp: $%04X"
", ps: $%04X"
", prefix: $%02x"
", opcode: $%02x"
", inst: "
, cpu->sp[thread]
, cpu->ps
, prefix
, opcode);
#if keypoll
pthread_mutex_unlock(&mutex);
#endif
#endif
addrsize = (prefix & 0x0C) >> 2;
rs = (prefix & 0x30) >> 4;
if (rs)
regsize = (1 << rs);
else
regsize = 1;
address = cpu->pc[thread];
cpu->pc[thread]++;
iclk++;
switch (optype[opcode]) {
case IMPL:
break;
case IMM:
switch (opcode) {
case TXS:
break;
case PHB:
case PHP:
case PHA:
case PHY:
case PHX:
case PLB:
case PLP:
case PLA:
case PLY:
case PLX:
case STT:
case LSL:
case LSR:
case ROL:
case ROR:
case ASR:
case ENT:
address = cpu->pc[thread];
cpu->pc[thread]+=1;
break;
default:
address = cpu->pc[thread];
cpu->pc[thread]+=regsize;
break;
}
break;
case ZM:
case ZMX:
case ZMY:
case IND:
case INDX:
case INDY:
tmp = 0;
address = addr[cpu->pc[thread]];
switch (addrsize) {
case 2:
address |= (uint64_t)addr[cpu->pc[thread]+5] << 40;
address |= (uint64_t)addr[cpu->pc[thread]+4] << 32;
tmp+=2;
case 3:
address |= addr[cpu->pc[thread]+3] << 24;
tmp+=1;
case 1:
address |= addr[cpu->pc[thread]+2] << 16;
address |= addr[cpu->pc[thread]+1] << 8;
tmp+=2;
case 0:
tmp+=1;
}
cpu->pc[thread]+=tmp;
tmpaddr = address;
iclk++;
reg = 0;
switch (optype[opcode]) {
case ZMX:
address += cpu->x[thread];
iclk++;
break;
case ZMY:
address += cpu->y[thread];
iclk++;
break;
case INDX:
address += cpu->x[thread];
iclk++;
case INDY:
if (optype[opcode] == INDX) {
reg = 0;
} else {
reg = cpu->y[thread];
iclk++;
}
case IND:
value = addr[address];
value += addr[address+1] << 8;
value += addr[address+2] << 16;
value += addr[address+3] << 24;
value += (uint64_t)addr[address+4] << 32;
value += (uint64_t)addr[address+5] << 40;
value += (uint64_t)addr[address+6] << 48;
value += (uint64_t)addr[address+7] << 56;
iclk++;
value += reg;
address = value;
value = 0;
reg = 0;
break;
}
break;
case ABS:
tmp = 0;
address = addr[cpu->pc[thread]];
switch (addrsize) {
case 3:
address |= (uint64_t)addr[cpu->pc[thread]+7] << 56;
tmp+=1;
case 2:
address |= (uint64_t)addr[cpu->pc[thread]+6] << 48;
address |= (uint64_t)addr[cpu->pc[thread]+5] << 40;
tmp+=2;
iclk++;
case 1:
address |= (uint64_t)addr[cpu->pc[thread]+4] << 32;
address |= addr[cpu->pc[thread]+3] << 24;
address |= addr[cpu->pc[thread]+2] << 16;
tmp+=3;
case 0:
address |= addr[cpu->pc[thread]+1] << 8;
tmp+=2;
}
cpu->pc[thread]+=tmp;
break;
}
value = addr[address];
switch (regsize) {
case 8:
value |= (uint64_t)addr[address+7] << 56;
value |= (uint64_t)addr[address+6] << 48;
value |= (uint64_t)addr[address+5] << 40;
value |= (uint64_t)addr[address+4] << 32;
case 4:
value |= addr[address+3] << 24;
value |= addr[address+2] << 16;
case 2:
value |= addr[address+1] << 8;
}
#if debug && !bench
#if keypoll
pthread_mutex_lock(&mutex);
#endif
char postfix[3];
char op[4];
op[0] = opname[opcode][0];
op[1] = opname[opcode][1];
op[2] = opname[opcode][2];
op[3] = '\0';
switch(regsize) {
case 1: postfix[0] = 0; postfix[1] = 0; postfix[2] = 0; break;
case 2: postfix[0] = '.'; postfix[1] = 'W'; postfix[2] = 0; break;
case 4: postfix[0] = '.'; postfix[1] = 'D'; postfix[2] = 0; break;
case 8: postfix[0] = '.'; postfix[1] = 'Q'; postfix[2] = 0; break;
}
switch (optype[opcode]) {
case IMPL: wprintw(scr, "%s\r" , opname[opcode]); break;
case IMM:
switch(regsize) {
case 1: wprintw(scr, "%s #$%02X\r" , op, value); break;
case 2: wprintw(scr, "%s%s #$%04X\r" , op, postfix, value); break;
case 4: wprintw(scr, "%s%s #$%08X\r" , op, postfix, value); break;
case 8: wprintw(scr, "%s%s #$%016llX\r" , op, postfix, value); break;
}
break;
case ZM:
case ZMX:
case ZMY:
switch (optype[opcode]) {
case ZMX: tmpaddr = address - cpu->x[thread]; break;
case ZMY: tmpaddr = address - cpu->y[thread]; break;
}
switch (addrsize) {
case 3: wprintw(scr, "%s%s $%08X%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
case 2: wprintw(scr, "%s%s $%014llX%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
case 1: wprintw(scr, "%s%s $%06X%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
case 0: wprintw(scr, "%s%s $%02X%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
}
break;
case IND:
case INDX:
case INDY:
switch (addrsize) {
case 3: wprintw(scr, "%s%s ($%08X%s\r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break;
case 2: wprintw(scr, "%s%s ($%012llX%s\r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break;
case 1: wprintw(scr, "%s%s ($%06X%s\r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break;
case 0: wprintw(scr, "%s%s ($%02X%s\r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break;
}
break;
case ABS:
tmpaddr = address;
switch (addrsize) {
case 3: wprintw(scr, "%s%s $%016llX\r" , op, postfix, tmpaddr); break;
case 2: wprintw(scr, "%s%s $%014llX\r" , op, postfix, tmpaddr); break;
case 1: wprintw(scr, "%s%s $%010llX\r" , op, postfix, tmpaddr); break;
case 0: wprintw(scr, "%s%s $%04X\r" , op, postfix, tmpaddr ); break;
}
break;
}
mvwprintw(scr, 27, 0, "TX_ADDR: $%02X, RX_ADDR: $%02X\r", addr[TX_ADDR], addr[RX_ADDR]);
mvwprintw(scr, 28, 0, "scr_ptr3: %04X\r", (addr[0x5C] << 8) | addr[0x5B]);
mvwprintw(scr, 29, 0, "address: $%016llx, scr_row: %02u, scr_col: %02u, scr_str: %02u, scr_end: %02u\r", address, addr[0], addr[1], addr[0x28], addr[0x29]);
mvwprintw(scr, 32, 0, "bitabl: %02x %02x %02x %02x %02x %02x %02x %02x "
"%02x %02x %02x %02x %02x %02x %02x %02x\r"
, addr[0x18], addr[0x19], addr[0x1A], addr[0x1B], addr[0x1C], addr[0x1D], addr[0x1E], addr[0x1F]
, addr[0x20], addr[0x21], addr[0x22], addr[0x23], addr[0x24], addr[0x25], addr[0x26], addr[0x27]);
uint8_t ln = 33;
uint16_t line_idx = 0;
uint16_t tmpad = 0x2000;
int row, col;
uint8_t iscursor = 0;
mvwprintw(scr, ln++, 0, "buffer:\r");
if (updt) {
scr_row = addr[0];
scr_col = addr[1];
wmove(scr, ln++, 0);
for (uint8_t i = 0; i < 10; i++) {
line_idx = (i << 6) + (i << 4);
for (uint8_t j = 0; j < 0x50; j++) {
wprintw(scr, "%02X", addr[tmpad+j+line_idx]);
if ((addr[0]+addr[0x28]) == i && addr[1] == j) {
iscursor=1;
getyx(scr,row, col);
wmove(scr, ln++, 0);
wclrtoeol(scr);
wmove(scr, row+1, col-2);
wprintw(scr, "/\\\r");
wmove(scr, row, col);
}
}
wprintw(scr, ", i: %02X\r", i);
if (!iscursor) {
wmove(scr, ln, 0);
wclrtoeol(scr);
}
iscursor = 0;
wmove(scr, ln++, 0);
}
updt = 0;
}
#if keypoll
pthread_mutex_unlock(&mutex);
#endif
lines+=1;
#endif
switch(opcode) {
case CPS:
cpu->ps &= 0;
break;
case AAB:
value = cpu->b[thread];
case ADC:
case ADC_AB:
case ADC_Z:
sum = cpu->a[thread]+value+getflag(C);
cpu->a[thread] = sum;
setflag(sum == 0, Z);
setflag((sum >> 63), N);
setflag(((cpu->a[thread]^value) >> 63) && ((cpu->a[thread]^sum) >> 63), V);
setflag((sum < value), C);
break;
case PHB:
case PHP:
case PHA:
case PHY:
case PHX:
tmp = value;
switch (opcode) {
case PHA: reg = cpu->a[thread]; break;
case PHB: reg = cpu->b[thread]; break;
case PHX: reg = cpu->x[thread]; break;
case PHY: reg = cpu->y[thread]; break;
case PHP: reg = cpu->ps; break;
}
if (tmp > 7)
tmp = 7;
switch (tmp) {
case 7: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (7<<3);
case 6: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (6<<3);
case 5: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (5<<3);
case 4: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (4<<3);
case 3: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (3<<3);
case 2: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (2<<3);
case 1: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (1<<3);
case 0: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg & 0xFF;
}
break;
case TAY:
case TAX:
case TYX:
case TYA:
case TXA:
case TXY:
case TAB:
case TSX:
case TBA:
case TXS:
switch (opcode) {
case TBA: cpu->a[thread] = cpu->b[thread]; reg = cpu->a[thread]; break;
case TXA: cpu->a[thread] = cpu->x[thread]; reg = cpu->a[thread]; break;
case TYA: cpu->a[thread] = cpu->y[thread]; reg = cpu->a[thread]; break;
case TAB: cpu->b[thread] = cpu->a[thread]; reg = cpu->b[thread]; break;
case TAY: cpu->y[thread] = cpu->a[thread]; reg = cpu->y[thread]; break;
case TXY: cpu->y[thread] = cpu->x[thread]; reg = cpu->y[thread]; break;
case TAX: cpu->x[thread] = cpu->a[thread]; reg = cpu->x[thread]; break;
case TYX: cpu->x[thread] = cpu->y[thread]; reg = cpu->x[thread]; break;
case TSX: cpu->x[thread] = cpu->sp[thread] & 0xFFFF; cpu->x[thread] = cpu->stk_st[thread] << 16; break;
case TXS: cpu->sp[thread] = cpu->x[thread];
if (prefix == 0x13 && (value == thread+1 || value > 8)) {
cpu->stk_st[thread] = value & 0xFF;
cpu->stk_st[thread] += value << 16;
cpu->pc[thread]+=2;
}
break;
}
setflag(reg == 0, Z);
setflag(reg >> 63, N);
break;
case JMP:
case JMP_Z:
case JMP_IN:
cpu->pc[thread] = address;
break;
case SAB:
value = cpu->b[thread];
case SBC:
case SBC_AB:
case SBC_Z:
sum = cpu->a[thread]-value-!getflag(C);
setflag(sum == 0, Z);
setflag(sum >> 63, N);
setflag(((cpu->a[thread]^value) >> 63) && ((cpu->a[thread]^sum) >> 63), V);
setflag((sum > value), C);
cpu->a[thread] = sum;
break;
case PLB:
case PLP:
case PLA:
case PLY:
case PLX:
tmp = value;
switch (opcode) {
case PLA: reg = cpu->a[thread]; break;
case PLB: reg = cpu->b[thread]; break;
case PLX: reg = cpu->x[thread]; break;
case PLY: reg = cpu->y[thread]; break;
case PLP: reg = cpu->ps; break;
}
if (tmp > 7)
tmp = 7;
tmp2 = 0;
cpu->sp[thread]++;reg = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] & 0xFF;tmp--;
switch (tmp) {
case 6: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
case 5: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
case 4: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
case 3: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
case 2: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
case 1: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
case 0: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
}
switch (opcode) {
case PLA: cpu->a[thread] = reg; break;
case PLB: cpu->b[thread] = reg; break;
case PLX: cpu->x[thread] = reg; break;
case PLY: cpu->y[thread] = reg; break;
case PLP: cpu->ps = reg; break;
}
break;
case JSR_IN:
case JSR:
stksize = adrsize[addrsize];
switch (stksize) {
case 7: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] >> (7<<3);
case 6: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] >> (6<<3);
case 5: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] >> (5<<3);
case 4: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] >> (4<<3);
case 3: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] >> (3<<3);
case 2: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] >> (2<<3);
case 1: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] >> (1<<3);
case 0: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] & 0xFF;
}
cpu->pc[thread] = address;
break;
case ABA:
value = cpu->b[thread];
case AND:
case AND_AB:
case AND_Z:
cpu->a[thread] &= value;
setflag(value == 0, Z);
setflag(value >> 63, N);
break;
case STT:
cpu->crt |= value;
for (uint8_t i = 0; i < 7; i++) {
if ((value >> i) & 1) {
address = (uint64_t)addr[tv+(i<<3)]
| (uint64_t)addr[tv+1+(i<<3)] << 8
| (uint64_t)addr[tv+2+(i<<3)] << 16
| (uint64_t)addr[tv+3+(i<<3)] << 24
| (uint64_t)addr[tv+4+(i<<3)] << 32
| (uint64_t)addr[tv+5+(i<<3)] << 40
| (uint64_t)addr[tv+6+(i<<3)] << 48
| (uint64_t)addr[tv+7+(i<<3)] << 56;
cpu->pc[i+1] = address;
}
}
break;
case BPO:
case BPO_Z:
if (!getflag(N))
cpu->pc[thread] = address;
break;
case OAB:
value = cpu->b[thread];
case ORA:
case ORA_AB:
case ORA_Z:
cpu->a[thread] |= value;
setflag(value == 0, Z);
setflag(value >> 63, N);
break;
case SEI:
setflag(1, I);
break;
case BNG:
case BNG_Z:
if (getflag(N))
cpu->pc[thread] = address;
break;
case XAB:
value = cpu->b[thread];
case XOR:
case XOR_AB:
case XOR_Z:
cpu->a[thread] ^= value;
setflag(value == 0, Z);
setflag(value >> 63, N);
break;
case CLI:
setflag(0, I);
break;
case BCS:
case BCS_Z:
if (getflag(C))
cpu->pc[thread] = address;
break;
case LLB:
value = cpu->b[thread];
case LSL:
case LSL_AB:
case LSL_Z:
sum = (value < 64) ? cpu->a[thread] << value : 0;
setflag(sum == 0, Z);
setflag(sum >> 63, N);
setflag(cpu->a[thread] >> 64-value, C);
cpu->a[thread] = sum;
break;
case SEC:
setflag(1, C);
break;
case STA:
case STY:
case STX:
case STB:
case STA_Z:
case STY_Z:
case STX_Z:
case STB_Z:
case STA_ZX:
case STY_ZX:
case STX_ZY:
case STB_ZX:
case STA_ZY:
case STB_ZY:
case STY_IN:
case STX_IN:
case STA_IN:
case STB_IN:
case STA_IX:
case STB_IX:
case STA_IY:
case STB_IY:
switch (opcode) {
case STB:
case STB_Z:
case STB_ZX:
case STB_ZY:
case STB_IN:
case STB_IX:
case STB_IY:
value = cpu->b[thread];
break;
case STA:
case STA_Z:
case STA_ZX:
case STA_ZY:
case STA_IN:
case STA_IX:
case STA_IY:
value = cpu->a[thread];
break;
case STY:
case STY_Z:
case STY_ZX:
case STY_IN:
value = cpu->y[thread];
break;
case STX:
case STX_Z:
case STX_ZY:
case STX_IN:
value = cpu->x[thread];
break;
}
addr[address] = value & 0xFF;
#if (IO || debug) && !branch
if (address == TX_ADDR) {
#if keypoll
pthread_mutex_lock(&mutex);
#endif
if (esc) {
switch(addr[TX_ADDR]) {
case 'A':
if (y > 0)
y--;
#if !debug
wmove(scr, y, x);
#endif
esc = 0;
break;
case 'B':
if (y < getmaxy(scr))
y++;
#if !debug
wmove(scr, y, x);
#endif
esc = 0;
break;
case 'C':
if (x < getmaxx(scr))
x++;
#if !debug
wmove(scr, y, x);
#endif
esc = 0;
break;
case 'D':
if (x > 0)
x--;
#if !debug
wmove(scr, y, x);
#endif
esc = 0;
break;
case 'H':
if (!bcd[2] && !bcd[3]) {
y = 0;
} else {
y = ((bcd[3]*10) + bcd[2]);
}
if (!bcd[0] && !bcd[1]) {
x = 0;
} else {
x = ((bcd[1]*10) + bcd[0]);
}
#if !debug
wmove(scr, y, x);
#else
updt = 1;
mvwprintw(scr, 30, 0, "x: %i, y: %i ", x, y);
mvwprintw(scr, 31, 0, "bcd[3-2]: {%u, %u}, bcd[1-0]: {%u, %u}", bcd[3], bcd[2], bcd[1], bcd[0]);
#endif
idx = 3;
bcd[0] = 0;
bcd[1] = 0;
bcd[2] = 0;
bcd[3] = 0;
esc = 0;
break;
case 'S':
#if !debug
wscrl(scr, -1);
#endif
esc = 0;
break;
case 'T':
#if !debug
wscrl(scr, 1);
#endif
esc = 0;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
bcd[idx--] = (addr[address] - '0');
break;
default:
iscol = (addr[address] == ';');
break;
}
} else {
switch (addr[TX_ADDR]) {
case 0xC:
x=0,y=0;
#if !debug
wclear(scr);
wmove(scr, y, x);
#endif
break;
case CURSES_BACKSPACE:
case '\b':
if (x > 0) {
x--;
#if !debug
wmove(scr, y, x);
#endif
}
#if !debug
wdelch(scr);
#else
updt = 1;
#endif
break;
case '\033':
esc = 1;
break;
case '\n':
#if !debug
wmove(scr, y, x);
waddch(scr, addr[address]);
#else
updt = (!addr[0x16]);
#endif
x = 0;
y+=1;
break;
default:
#if !debug
wmove(scr, y, x);
waddch(scr, addr[address]);
#else
updt = (!addr[0x16]);
#endif
x+=1;
break;
}
}
#if keypoll
pthread_mutex_unlock(&mutex);
#endif
}
#endif
switch (regsize) {
case 8:
addr[address+7] = value >> 56;
addr[address+6] = value >> 48;
addr[address+5] = value >> 40;
addr[address+4] = value >> 32;
case 4:
addr[address+3] = value >> 24;
addr[address+2] = value >> 16;
case 2:
addr[address+1] = value >> 8;
}
break;
case BCC:
case BCC_Z:
if (!getflag(C))
cpu->pc[thread] = address;
break;
case LRB:
value = cpu->b[thread];
case LSR:
case LSR_AB:
case LSR_Z:
sum = (value < 64) ? cpu->a[thread] >> value : 0;
setflag(sum == 0, Z);
setflag(sum >> 63, N);
setflag(cpu->a[thread] & 1, C);
cpu->a[thread] = sum;
break;
case ARB:
value = cpu->b[thread];
case ASR:
case ASR_AB:
case ASR_Z:
sign = cpu->a[thread] >> 63;
sum = (value < 64) ? (cpu->a[thread] >> value) | sign : 0;
setflag(sum == 0, Z);
setflag(sum >> 63, N);
setflag(cpu->a[thread] & 1, C);
cpu->a[thread] = sum;
break;
case CLC:
setflag(0, C);
break;
case LDB:
case LDA:
case LDY:
case LDX:
case LDB_AB:
case LDA_AB:
case LDY_AB:
case LDX_AB:
case LDB_Z:
case LDA_Z:
case LDY_Z:
case LDX_Z:
case LDB_ZX:
case LDA_ZX:
case LDY_ZX:
case LDX_ZY:
case LDB_ZY:
case LDA_ZY:
case LDB_IN:
case LDA_IN:
case LDY_IN:
case LDX_IN:
case LDB_IX:
case LDA_IX:
case LDB_IY:
case LDA_IY:
if (address == CTRL_ADDR) {
kbd_rdy = 1;
pthread_mutex_lock(&main_mutex);
pthread_cond_signal(&main_cond);
pthread_mutex_unlock(&main_mutex);
#if !keypoll
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
#endif
kbd_rdy = 0;
}
value = addr[address];
switch (regsize) {
case 8:
value |= (uint64_t)addr[address+7] << 56;
value |= (uint64_t)addr[address+6] << 48;
value |= (uint64_t)addr[address+5] << 40;
value |= (uint64_t)addr[address+4] << 32;
case 4:
value |= addr[address+3] << 24;
value |= addr[address+2] << 16;
case 2:
value |= addr[address+1] << 8;
}
switch (opcode) {
case LDB:
case LDB_AB:
case LDB_Z:
case LDB_ZX:
case LDB_ZY:
case LDB_IN:
case LDB_IX:
case LDB_IY:
cpu->b[thread] = value;
break;
case LDA:
case LDA_AB:
case LDA_Z:
case LDA_ZX:
case LDA_ZY:
case LDA_IN:
case LDA_IX:
case LDA_IY:
cpu->a[thread] = value;
break;
case LDY:
case LDY_AB:
case LDY_Z:
case LDY_ZX:
case LDY_IN:
cpu->y[thread] = value;
break;
case LDX:
case LDX_AB:
case LDX_Z:
case LDX_ZY:
case LDX_IN:
cpu->x[thread] = value;
break;
}
setflag(value == 0, Z);
setflag(value >> 63, N);
break;
case BEQ:
case BEQ_Z:
if (getflag(Z))
cpu->pc[thread] = address;
break;
case RLB:
value = cpu->b[thread];
case ROL:
case ROL_AB:
case ROL_Z:
sum = cpu->a[thread] << value;
sum |= getflag(C);
setflag(sum == 0, Z);
setflag(sum >> 63, N);
setflag(cpu->a[thread] >> (uint64_t)64-value, C);
cpu->a[thread] = sum;
break;
case BNE:
case BNE_Z:
if (!getflag(Z))
cpu->pc[thread] = address;
break;
case RRB:
value = cpu->b[thread];
case ROR:
case ROR_AB:
case ROR_Z:
sum = cpu->a[thread] >> value;
sum |= (uint64_t)getflag(C) << (uint64_t)64-value;
setflag(sum == 0, Z);
setflag(sum >> 63, N);
setflag(cpu->a[thread] & 1, C);
cpu->a[thread] = sum;
break;
case BVS:
case BVS_Z:
if (getflag(V))
cpu->pc[thread] = address;
break;
case MAB:
value = cpu->b[thread];
case MUL:
case MUL_AB:
case MUL_Z:
sum = cpu->a[thread]*value+getflag(C);
cpu->a[thread] = sum;
setflag(sum == 0, Z);
setflag(sum >> 63, N);
setflag(!((cpu->a[thread]^value) >> 63) && ((cpu->a[thread]^sum) >> 63), V);
setflag((!((cpu->a[thread]^sum) && (cpu->a[thread]^value)) && (cpu->a[thread] >= ((uint64_t)1 << 32) && value >= ((uint64_t)1 << 32))), C);
break;
case BVC:
case BVC_Z:
if (!getflag(V))
cpu->pc[thread] = address;
break;
case DIV:
case DAB:
case DIV_AB:
case DIV_Z:
if (opcode != DAB) {
cpu->b[thread] = cpu->a[thread] % value;
} else {
value = cpu->b[thread];
cpu->x[thread] = cpu->a[thread] % value;
}
sum = cpu->a[thread]/value;
cpu->a[thread] = sum;
setflag(sum == 0, Z);
setflag((sum >> 63), N);
break;
case CLV:
setflag(0, V);
break;
case RTS:
tmp2 = 0;
stksize = adrsize[addrsize];
cpu->sp[thread]++;reg = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] & 0xFF;stksize--;
switch (stksize) {
case 4: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
case 3: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
case 2: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
case 1: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
case 0: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
}
break;
case CAB:
value = cpu->b[thread];
case CPB:
case CMP:
case CPY:
case CPX:
case CPY_AB:
case CPX_AB:
case CMP_AB:
case CPB_AB:
case CPY_Z:
case CPX_Z:
case CMP_Z:
case CPB_Z:
case CPY_IN:
case CPX_IN:
case CMP_IN:
case CPB_IN:
case CMP_IX:
case CPB_IX:
case CMP_IY:
case CPB_IY:
switch (opcode) {
case CPB:
case CPB_AB:
case CPB_Z:
case CPB_IN:
case CPB_IX:
case CPB_IY:
reg = cpu->b[thread];
break;
case CMP:
case CAB:
case CMP_AB:
case CMP_Z:
case CMP_IN:
case CMP_IX:
case CMP_IY:
reg = cpu->a[thread];
break;
case CPY:
case CPY_AB:
case CPY_Z:
case CPY_IN:
reg = cpu->y[thread];
break;
case CPX:
case CPX_AB:
case CPX_Z:
case CPX_IN:
reg = cpu->x[thread];
break;
}
sum = reg-value;
setflag(sum >> 63, N);
setflag(((reg^value) >> 63) && ((reg^sum) >> 63), V);
setflag(sum == 0, Z);
setflag(reg >= value, C);
break;
case ENT:
cpu->crt &= ~value;
for (uint8_t i = 0; i < 7; i++)
if ((value >> i) & 1)
cpu->pc[i+1] = cpu->pc[0]+(i+1);
break;
case RTI:
cpu->sp[thread] += 9;
cpu->ps = addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-8)] << (thread << 3);
cpu->pc[thread] = (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-7)];
cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-6)] << 8;
cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-5)] << 16;
cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-4)] << 24;
cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-3)] << 32;
cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-2)] << 40;
cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-1)] << 48;
cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << 56;
break;
case INC:
case INB:
case INY:
case INX:
switch (opcode) {
case INC: cpu->a[thread]+=1; reg = cpu->a[thread]; break;
case INB: cpu->b[thread]+=1; reg = cpu->b[thread]; break;
case INY: cpu->y[thread]+=1; reg = cpu->y[thread]; break;
case INX: cpu->x[thread]+=1; reg = cpu->x[thread]; break;
}
setflag(reg == 0, Z);
setflag(reg >> 63, N);
break;
case DEC:
case DEB:
case DEY:
case DEX:
switch (opcode) {
case DEC: cpu->a[thread]-=1; reg = cpu->a[thread]; break;
case DEB: cpu->b[thread]-=1; reg = cpu->b[thread]; break;
case DEY: cpu->y[thread]-=1; reg = cpu->y[thread]; break;
case DEX: cpu->x[thread]-=1; reg = cpu->x[thread]; break;
}
setflag(reg == 0, Z);
setflag(reg >> 63, N);
break;
case JSL:
stksize = adrsize[addrsize+4];
switch (stksize) {
case 7: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> (7<<3);cpu->sp[thread]--;
case 6: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> (6<<3);cpu->sp[thread]--;
case 5: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> (5<<3);cpu->sp[thread]--;
case 4: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> (4<<3);cpu->sp[thread]--;
case 3: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> (3<<3);cpu->sp[thread]--;
case 2: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> (2<<3);cpu->sp[thread]--;
case 1: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> (1<<3);cpu->sp[thread]--;
case 0: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] & 0xFF; cpu->sp[thread]--;
}
cpu->pc[thread] = address;
break;
case INC_AB:
case INC_Z:
addr[address]++;
setflag(addr[address] == 0, Z);
setflag(addr[address] >> 7, N);
break;
case NOP:
break;
case RTL:
tmp2 = 1;
stksize = adrsize[addrsize+4];
cpu->sp[thread] += 2;
stksize -= 2;
cpu->pc[thread] = addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-1)] & 0xFF;
cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << 8;
switch (stksize) {
case 5: cpu->sp[thread]++;tmp2++;cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
case 4: cpu->sp[thread]++;tmp2++;cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
case 3: cpu->sp[thread]++;tmp2++;cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
case 2: cpu->sp[thread]++;tmp2++;cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
case 1: cpu->sp[thread]++;tmp2++;cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
case 0: cpu->sp[thread]++;tmp2++;cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
}
break;
break;
case DEC_AB:
case DEC_Z:
addr[address]--;
setflag(addr[address] == 0, Z);
setflag(addr[address] >> 7, N);
break;
case BRK:
addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> 56;
addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-1)] = (uint64_t)cpu->pc[thread] >> 48;
addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-2)] = (uint64_t)cpu->pc[thread] >> 40;
addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-3)] = (uint64_t)cpu->pc[thread] >> 32;
addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-4)] = (uint64_t)cpu->pc[thread] >> 24;
addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-5)] = (uint64_t)cpu->pc[thread] >> 16;
addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-6)] = (uint64_t)cpu->pc[thread] >> 8;
addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-7)] = (uint64_t)cpu->pc[thread] & 0xFF;
addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-8)] = (uint64_t)cpu->ps >> (thread << 3);
cpu->sp[thread] -= 9;
setflag(1, I);
cpu->pc[thread] = (uint64_t)addr[0xFFE0];
cpu->pc[thread] += (uint64_t)addr[0xFFE1] << 8;
cpu->pc[thread] += (uint64_t)addr[0xFFE2] << 16;
cpu->pc[thread] += (uint64_t)addr[0xFFE3] << 24;
cpu->pc[thread] += (uint64_t)addr[0xFFE4] << 32;
cpu->pc[thread] += (uint64_t)addr[0xFFE5] << 40;
cpu->pc[thread] += (uint64_t)addr[0xFFE6] << 48;
cpu->pc[thread] += (uint64_t)addr[0xFFE7] << 56;
break;
case WAI:
wai = 1;
pthread_mutex_lock(&main_mutex);
pthread_cond_signal(&main_cond);
pthread_mutex_unlock(&main_mutex);
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
break;
default:
break;
}
ins++;
step = addr[STEP_ADDR];
#if !bench
if (step) {
pthread_mutex_lock(&main_mutex);
pthread_cond_signal(&main_cond);
pthread_mutex_unlock(&main_mutex);
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
#if debug
wrefresh(scr);
#endif
}
#endif
#if debug && !bench
#if keypoll
pthread_mutex_lock(&mutex);
#endif
mvwprintw(scr, (6*thread)+1, 0, "Instructions executed: %llu, Clock cycles: %llu\r", ins, iclk);
if (!step) {
wrefresh(scr);
}
#if keypoll
pthread_mutex_unlock(&mutex);
#endif
#elif bench
if (ins >= BENCH_INST) {
end = 1;
pthread_mutex_lock(&main_mutex);
threads_done++;
inst[thread] = ins;
clk[thread] = iclk;
pthread_cond_signal(&main_cond);
pthread_mutex_unlock(&main_mutex);
gettimeofday(&en[thread], 0);
}
#endif
}
free(s);
}
int main(int argc, char **argv) {
struct suxthr thr[THREADS];
char *tmp = malloc(2048);
ibcount = 0;
addr = malloc(0x04000000);
inss = 0;
int v = 0;
if (argc != 2) {
if (asmmon("stdin") == 2)
return 0;
} else {
if (asmmon(argv[1]) == 2)
return 0;
}
sprintf(tmp, "\033[2J\033[H");
fwrite(tmp, sizeof(char), strlen(tmp), stdout);
fflush(stdout);
#if !bench
if(!scr)
scr = initscr();
nodelay(stdscr, 0);
crmode();
noecho();
nl();
curs_set(1);
werase(scr);
scrollok(scr, 1);
start_color();
use_default_colors();
init_pair(1, COLOR_WHITE, -1);
attron(COLOR_PAIR(1) | A_BOLD);
wmove(scr, 0, 0);
wrefresh(scr);
#endif
pthread_t therads[THREADS];
int result;
for (int i = 0; i < THREADS; i++) {
thr[i].sx.sp[i] = 0xFFFF;
thr[i].sx.stk_st[i] = i+1;
if (i) {
thr[i].sx.a[i] = 0;
thr[i].sx.b[i] = 0;
thr[i].sx.x[i] = 0;
thr[i].sx.y[i] = 0;
thr[i].sx.pc[i] = (uint64_t)addr[0xFF50+(8*(i-1))]
| (uint64_t)addr[0xFF51+(8*(i-1))] << 8
| (uint64_t)addr[0xFF52+(8*(i-1))] << 16
| (uint64_t)addr[0xFF53+(8*(i-1))] << 24
| (uint64_t)addr[0xFF54+(8*(i-1))] << 32
| (uint64_t)addr[0xFF55+(8*(i-1))] << 40
| (uint64_t)addr[0xFF56+(8*(i-1))] << 48
| (uint64_t)addr[0xFF57+(8*(i-1))] << 56;
} else {
thr[i].sx.a[i] = 0;
thr[i].sx.b[i] = 0;
thr[i].sx.x[i] = 0;
thr[i].sx.y[i] = 0;
thr[i].sx.pc[i] = (uint64_t)addr[0xFFC0]
| (uint64_t)addr[0xFFC1] << 8
| (uint64_t)addr[0xFFC2] << 16
| (uint64_t)addr[0xFFC3] << 24
| (uint64_t)addr[0xFFC4] << 32
| (uint64_t)addr[0xFFC5] << 40
| (uint64_t)addr[0xFFC6] << 48
| (uint64_t)addr[0xFFC7] << 56;
}
thr[i].th = i;
inst[i] = 0;
result = pthread_create(&therads[i], NULL, run, &thr[i]);
assert(!result);
}
int c = 0;
uint8_t step_key = 0;
#if !bench
werase(scr);
#endif
while (threads_done < THREADS) {
#if !bench
int x, y;
if ((step_key && step && !kbd_rdy) || !step || kbd_rdy) {
if ((c != EOF && c !=-1)) {
pthread_mutex_lock(&main_mutex);
curs_set(0);
pthread_cond_wait(&main_cond, &main_mutex);
pthread_mutex_unlock(&main_mutex);
curs_set(1);
c = 0;
step_key = 0;
addr[CTRL_ADDR] = 0;
#if !debug
wrefresh(scr);
#endif
}
}
#if keypoll
pthread_mutex_lock(&mutex);
#endif
getyx(scr, y, x);
c = wgetch(scr);
if (c == 19) {
step = 1;
if (kbd_rdy)
c = wgetch(scr);
}
if (kbd_rdy) {
switch (c) {
case ERR:
addr[CTRL_ADDR] = 0;
break;
default:
if (kbd_rdy && c < 0x100) {
addr[RX_ADDR] = (uint8_t)c;
addr[CTRL_ADDR] = 1;
#if debug && !bench
wmove(scr, getmaxy(scr)-1, 0);
wprintw(scr, "c: %i, x: %i, y: %i", c, x, y);
wmove(scr, y, x);
wrefresh(scr);
#endif
}
#if !keypoll
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
#endif
break;
}
} else {
if ((c == 19 || c == 18) && step) {
if (c == 18)
step = 0;
else if (c == 19)
step_key = 1;
#if !keypoll
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
#endif
}
}
addr[STEP_ADDR] = step;
#if keypoll
pthread_mutex_unlock(&mutex);
#endif
#else
pthread_mutex_lock(&main_mutex);
pthread_cond_wait(&main_cond, &main_mutex);
pthread_mutex_unlock(&main_mutex);
#endif
}
#if bench
if (threads_done == THREADS) {
double tm_sec, tm_usec, tm[THREADS], ttm;
double clkspd;
double mhz;
double ips[THREADS];
double ipst;
for (int i = 0; i < THREADS; i++) {
tm_sec = (en[i].tv_sec - str[i].tv_sec);
tm_usec = (en[i].tv_usec-str[i].tv_usec);
tm[i] = (tm_sec*1000000)+(tm_usec);
ips[i] = inst[i]/tm[i];
if (i) {
inss += inst[i];
ttm += tm[i];
ipst += ips[i];
tclk += clk[i];
} else {
inss = inst[i];
ttm = tm[i];
ipst = ips[i];
tclk = clk[i];
}
clkspd = (tm[i]/1000000)*1000000/clk[i];
mhz = 1000000.0/clkspd/1000000;
sprintf(tmp, "Instructions executed for thread %i: %llu, Instructions per Second for thread %i in MIPS: %f, tm: %f\n", i, inst[i], i, ips[i], tm[i]/1000000);
fwrite(tmp, sizeof(char), strlen(tmp), stdout);
}
clkspd = (ttm/1000000)*1000000/tclk;
mhz = 1000000.0/clkspd/1000000;
sprintf(tmp, "Total Instructions executed: %llu, Total Instructions per Second in MIPS: %f, Clock cycles: %llu, Clock Speed in MHz: %f, tm: %f\n", inss, ipst, tclk, mhz, ttm/1000000);
fwrite(tmp, sizeof(char), strlen(tmp), stdout);
fflush(stdout);
free(tmp);
}
#endif
free(addr);
return 0;
}