Some checks are pending
Build / cmake-builds (push) Waiting to run
Build / makefile (macos-latest, besm6 imlac tt2500 microvax3900 microvax1 rtvax1000 vaxstation3100m76 vaxstation4000m60) (push) Waiting to run
Build / makefile (macos-latest, id16 id32 sds lgp h316 cdc1700 swtp6800mp-a swtp6800mp-a2 tx-0 ssem b5500 sage pdq3 alpha) (push) Waiting to run
Build / makefile (macos-latest, microvax2 vax730 vax750 vax780 vax8200 vax8600 microvax2000 infoserver100 infoserver150vxt microvax3100 microvax3100e vaxstation3100m30 vaxstation3100m38) (push) Waiting to run
Build / makefile (macos-latest, microvax3100m80 vaxstation4000vlc infoserver1000 nova eclipse hp2100 hp3000 i1401 i1620 s3 altair altairz80 gri i7094) (push) Waiting to run
Build / makefile (macos-latest, pdp1 pdp4 pdp6 pdp7 pdp8 pdp9 pdp10 pdp10-ka pdp10-ki pdp10-kl pdp10-ks pdp11 pdp15 vax) (push) Waiting to run
Build / makefile (macos-latest, scelbi 3b2 i701 i704 i7010 i7070 i7080 i7090 sigma uc15 i650 sel32 intel-mds ibm1130) (push) Waiting to run
Build / makefile (ubuntu-latest, besm6 imlac tt2500 microvax3900 microvax1 rtvax1000 vaxstation3100m76 vaxstation4000m60) (push) Waiting to run
Build / makefile (ubuntu-latest, id16 id32 sds lgp h316 cdc1700 swtp6800mp-a swtp6800mp-a2 tx-0 ssem b5500 sage pdq3 alpha) (push) Waiting to run
Build / makefile (ubuntu-latest, microvax2 vax730 vax750 vax780 vax8200 vax8600 microvax2000 infoserver100 infoserver150vxt microvax3100 microvax3100e vaxstation3100m30 vaxstation3100m38) (push) Waiting to run
Build / makefile (ubuntu-latest, microvax3100m80 vaxstation4000vlc infoserver1000 nova eclipse hp2100 hp3000 i1401 i1620 s3 altair altairz80 gri i7094) (push) Waiting to run
Build / makefile (ubuntu-latest, pdp1 pdp4 pdp6 pdp7 pdp8 pdp9 pdp10 pdp10-ka pdp10-ki pdp10-kl pdp10-ks pdp11 pdp15 vax) (push) Waiting to run
Build / makefile (ubuntu-latest, scelbi 3b2 i701 i704 i7010 i7070 i7080 i7090 sigma uc15 i650 sel32 intel-mds ibm1130) (push) Waiting to run
478 lines
11 KiB
C
478 lines
11 KiB
C
#include <jansson.h>
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
#include <sys/stat.h>
|
|
|
|
#include "pdp11_defs.h"
|
|
#include "sim_defs.h"
|
|
|
|
//extern t_stat sim_brk_init(void);
|
|
//extern t_stat sim_brk_set(t_addr loc, int32 sw, int32 ncnt, CONST char *act);
|
|
extern t_stat sim_instr();
|
|
//extern uint32 sim_brk_summ;
|
|
extern void PWriteW(int32 data, int32 addr);
|
|
extern int32 PReadW(int32 addr);
|
|
extern int32 REGFILE[6][2];
|
|
extern int32 STACKFILE[4];
|
|
extern int32 saved_PC;
|
|
extern int32 PSW;
|
|
extern t_stat cpu_reset(DEVICE *dptr);
|
|
extern DEVICE cpu_dev;
|
|
extern int32 STACKFILE[4];
|
|
extern int32 sim_interval;
|
|
|
|
struct mem_t {
|
|
uint32_t addr;
|
|
uint16_t value;
|
|
};
|
|
|
|
int is_prime(int n) {
|
|
if (n <= 1)
|
|
return 0;
|
|
for(int i = 2; i*i <= n; i++) {
|
|
if (n % i == 0)
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int file_exist(const char *const filename)
|
|
{
|
|
struct stat st;
|
|
return stat(filename, &st) == 0;
|
|
}
|
|
|
|
uint16_t test_values[65536];
|
|
int n_test_values = 0;
|
|
|
|
void generate_test_values()
|
|
{
|
|
for(int i=1; i<65536; i+=28) {
|
|
if (is_prime(i))
|
|
test_values[n_test_values++] = i;
|
|
}
|
|
|
|
for(int i=1; i<16; i++)
|
|
test_values[n_test_values++] = 1 << i;
|
|
|
|
test_values[n_test_values++] = 0;
|
|
test_values[n_test_values++] = 255;
|
|
test_values[n_test_values++] = 32767;
|
|
test_values[n_test_values++] = 65535;
|
|
}
|
|
|
|
json_t *generate_test(uint16_t instruction, int *const id, struct mem_t *mem, size_t n_mem)
|
|
{
|
|
json_t *before = json_object();
|
|
|
|
json_object_set(before, "PC", json_integer(saved_PC));
|
|
|
|
json_object_set(before, "stack-0", json_integer(STACKFILE[0]));
|
|
json_object_set(before, "stack-1", json_integer(STACKFILE[1]));
|
|
json_object_set(before, "stack-2", json_integer(STACKFILE[2]));
|
|
json_object_set(before, "stack-3", json_integer(STACKFILE[3]));
|
|
|
|
json_t *memory_i = json_array();
|
|
|
|
for(size_t i=0; i<n_mem; i++) {
|
|
char buffer[16];
|
|
json_t *put_mem_i_0 = json_object();
|
|
PWriteW(mem[i].value, mem[i].addr);
|
|
|
|
sprintf(buffer, "%06o", mem[i].addr);
|
|
json_object_set(put_mem_i_0, buffer, json_integer(mem[i].value));
|
|
json_array_append_new(memory_i, put_mem_i_0);
|
|
}
|
|
|
|
json_object_set(before, "memory", memory_i);
|
|
|
|
for(int k=0; k<6; k++) {
|
|
char name[16];
|
|
|
|
sprintf(name, "reg-%d.%d", k, 0);
|
|
json_object_set(before, name, json_integer(REGFILE[k][0]));
|
|
|
|
sprintf(name, "reg-%d.%d", k, 1);
|
|
json_object_set(before, name, json_integer(REGFILE[k][1]));
|
|
}
|
|
|
|
json_object_set(before, "PSW", json_integer(PSW));
|
|
|
|
// do
|
|
int failed = sim_instr() != 0;
|
|
|
|
json_t *after = json_object();
|
|
json_object_set(after, "PC", json_integer(saved_PC));
|
|
|
|
for(int k=0; k<6; k++) {
|
|
char name[16];
|
|
|
|
sprintf(name, "reg-%d.%d", k, 0);
|
|
json_object_set(after, name, json_integer(REGFILE[k][0]));
|
|
|
|
sprintf(name, "reg-%d.%d", k, 1);
|
|
json_object_set(after, name, json_integer(REGFILE[k][1]));
|
|
}
|
|
|
|
json_object_set(after, "PSW", json_integer(PSW));
|
|
|
|
json_object_set(after, "stack-0", json_integer(STACKFILE[0]));
|
|
json_object_set(after, "stack-1", json_integer(STACKFILE[1]));
|
|
json_object_set(after, "stack-2", json_integer(STACKFILE[2]));
|
|
json_object_set(after, "stack-3", json_integer(STACKFILE[3]));
|
|
|
|
json_t *memory_o = json_array();
|
|
|
|
for(size_t i=0; i<n_mem; i++) {
|
|
char buffer[16];
|
|
sprintf(buffer, "%06o", mem[i].addr);
|
|
|
|
json_t *get_mem = json_object();
|
|
json_object_set(get_mem, buffer, json_integer(PReadW(mem[i].addr)));
|
|
json_array_append_new(memory_o, get_mem);
|
|
}
|
|
|
|
json_object_set(after, "memory", memory_o);
|
|
|
|
json_t *collection = json_object();
|
|
json_object_set(collection, "id", json_integer(*id));
|
|
(*id)++;
|
|
json_object_set(collection, "before", before);
|
|
json_object_set(collection, "after", after);
|
|
|
|
if (failed) {
|
|
json_decref(collection);
|
|
return NULL;
|
|
}
|
|
|
|
return collection;
|
|
}
|
|
|
|
void init_simh()
|
|
{
|
|
// reset_all(0); is this required?
|
|
cpu_reset(&cpu_dev);
|
|
sim_interval = 32767;
|
|
}
|
|
|
|
void randomize_registers_all_values()
|
|
{
|
|
for(int k=0; k<6; k++) {
|
|
REGFILE[k][0] = rand() & 0xffff;
|
|
REGFILE[k][1] = rand() & 0xffff;
|
|
}
|
|
}
|
|
|
|
void init_stack_registers()
|
|
{
|
|
STACKFILE[0] = STACKFILE[1] = STACKFILE[2] = STACKFILE[3] = 010000;
|
|
}
|
|
|
|
void dump_json(const char *const filename, json_t *const j)
|
|
{
|
|
FILE *fh = fopen(filename, "w");
|
|
json_dumpf(j, fh, JSON_INDENT(1));
|
|
fclose(fh);
|
|
|
|
json_decref(j);
|
|
}
|
|
|
|
void emit_branch_instructions()
|
|
{
|
|
printf("Branch instructions\n");
|
|
const char *const filename = "pdp1170-valtest-COND-BRANCHES.json";
|
|
if (file_exist(filename))
|
|
return;
|
|
int id = 0;
|
|
json_t *out = json_array();
|
|
for(int group=0; group<2; group++) {
|
|
for(int bt=0; bt<8; bt++) {
|
|
if (group == 0 && bt == 0) // SWAB
|
|
continue;
|
|
for(int direction=0; direction<4; direction++) {
|
|
uint16_t instr = (group << 15) | (bt << 8);
|
|
|
|
if (direction & 2)
|
|
instr |= 62 + (direction & 1);
|
|
else
|
|
instr |= 218 + (direction & 1);
|
|
|
|
for(int psw_val=0; psw_val<16; psw_val++) {
|
|
init_simh();
|
|
|
|
saved_PC = 0100;
|
|
|
|
randomize_registers_all_values();
|
|
|
|
init_stack_registers();
|
|
|
|
struct mem_t mem[1] = {
|
|
{ 0100, instr }
|
|
};
|
|
|
|
PSW = psw_val;
|
|
|
|
json_t *obj = generate_test(instr, &id, mem, 1);
|
|
if (obj)
|
|
json_array_append_new(out, obj);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
dump_json(filename, out);
|
|
}
|
|
|
|
void emit_condition_sets()
|
|
{
|
|
printf("Condition set instructions\n");
|
|
const char *const filename = "pdp1170-valtest-CONDITIONS.json";
|
|
if (file_exist(filename))
|
|
return;
|
|
int id = 0;
|
|
json_t *out = json_array();
|
|
for(int condition=0; condition<16; condition++) {
|
|
uint16_t instr = 0240 + condition;
|
|
|
|
for(int psw_val=0; psw_val<16; psw_val++) {
|
|
init_simh();
|
|
|
|
saved_PC = 0100;
|
|
|
|
randomize_registers_all_values();
|
|
|
|
init_stack_registers();
|
|
|
|
struct mem_t mem[1] = {
|
|
{ 0100, instr }
|
|
};
|
|
|
|
PSW = psw_val;
|
|
|
|
json_t *obj = generate_test(instr, &id, mem, 1);
|
|
if (obj)
|
|
json_array_append_new(out, obj);
|
|
}
|
|
}
|
|
dump_json(filename, out);
|
|
}
|
|
|
|
void emit_add_sub_c()
|
|
{
|
|
printf("ADD/SUB/ADC/SBC instructions\n");
|
|
const char *const filename = "pdp1170-valtest-ADD_SUB_ADC_SBC.json";
|
|
if (file_exist(filename))
|
|
return;
|
|
int id = 0;
|
|
json_t *out = json_array();
|
|
int count = 0;
|
|
int total = n_test_values * n_test_values * 4 * 2;
|
|
time_t start = time(NULL);
|
|
for(int group=0; group<4; group++) {
|
|
uint16_t instr = 0;
|
|
int word = group & 1;
|
|
|
|
if (group == 0 || group == 1)
|
|
instr = (6 << 12 /* instr */) | (word << 15 /* ADD/SUB */) | (1 << 6 /* src=R1 */);
|
|
else if (group == 2)
|
|
instr = (055 << 6 /* instr */) | (word << 15 /* ADCb/ADCw */) | (1 << 6 /* src=R1 */);
|
|
else if (group == 3)
|
|
instr = (056 << 6 /* instr */) | (word << 15 /* SBCb/SBCw */) | (1 << 6 /* src=R1 */);
|
|
|
|
for(int v1=0; v1<n_test_values; v1++) {
|
|
for(int v2=0; v2<n_test_values; v2++) {
|
|
for(int psw_val=0; psw_val<2; psw_val++) {
|
|
count++;
|
|
|
|
init_simh();
|
|
|
|
saved_PC = 0100;
|
|
|
|
randomize_registers_all_values();
|
|
REGFILE[0][0] = REGFILE[0][1] = v1;
|
|
REGFILE[1][0] = REGFILE[1][1] = v2;
|
|
|
|
init_stack_registers();
|
|
|
|
struct mem_t mem[1] = {
|
|
{ 0100, instr }
|
|
};
|
|
|
|
PSW = psw_val;
|
|
|
|
json_t *obj = generate_test(instr, &id, mem, 1);
|
|
if (obj)
|
|
json_array_append_new(out, obj);
|
|
}
|
|
}
|
|
|
|
printf("%.2f%% %f \r", count * 100 / (double)total, total / (double)count * (time(NULL) - start));
|
|
fflush(NULL);
|
|
}
|
|
}
|
|
dump_json(filename, out);
|
|
}
|
|
|
|
void emit_cmp()
|
|
{
|
|
printf("CMP instructions\n");
|
|
const char *const filename = "pdp1170-valtest-CMP.json";
|
|
if (file_exist(filename))
|
|
return;
|
|
int id = 0;
|
|
json_t *out = json_array();
|
|
int count = 0;
|
|
int total = n_test_values * n_test_values * 2 * 2;
|
|
time_t start = time(NULL);
|
|
for(int group=0; group<2; group++) {
|
|
uint16_t instr = 0;
|
|
int word = group & 1;
|
|
|
|
if (group == 0 || group == 1)
|
|
instr = (2 << 12 /* instr */) | (word << 15 /* CMPb/CMPw */) | (1 << 6 /* src=R1 */);
|
|
|
|
for(int v1=0; v1<n_test_values; v1++) {
|
|
for(int v2=0; v2<n_test_values; v2++) {
|
|
for(int psw_val=0; psw_val<2; psw_val++) {
|
|
count++;
|
|
|
|
init_simh();
|
|
|
|
saved_PC = 0100;
|
|
|
|
randomize_registers_all_values();
|
|
REGFILE[0][0] = REGFILE[0][1] = v1;
|
|
REGFILE[1][0] = REGFILE[1][1] = v2;
|
|
|
|
init_stack_registers();
|
|
|
|
struct mem_t mem[1] = {
|
|
{ 0100, instr }
|
|
};
|
|
|
|
PSW = psw_val;
|
|
|
|
json_t *obj = generate_test(instr, &id, mem, 1);
|
|
if (obj)
|
|
json_array_append_new(out, obj);
|
|
}
|
|
}
|
|
|
|
printf("%.2f%% %f \r", count * 100 / (double)total, total / (double)count * (time(NULL) - start));
|
|
fflush(NULL);
|
|
}
|
|
}
|
|
dump_json(filename, out);
|
|
}
|
|
|
|
void emit_add_double_oper_instr()
|
|
{
|
|
printf("addition double operand instructions\n");
|
|
const char *const filename = "pdp1170-valtest-DOUB_OPER-INSTR.json";
|
|
if (file_exist(filename))
|
|
return;
|
|
int id = 0;
|
|
json_t *out = json_array();
|
|
int count = 0;
|
|
int total = n_test_values * n_test_values * (8 - 2);
|
|
time_t start = time(NULL);
|
|
for(int group=0; group<8; group++) {
|
|
uint16_t instr = (7 << 12) | (group << 9 /* instr */) | (1 << 6 /* src=R1 */);
|
|
|
|
if (group == 5 || group == 6)
|
|
continue;
|
|
|
|
for(int v1=0; v1<n_test_values; v1++) {
|
|
for(int v2=0; v2<n_test_values; v2++) {
|
|
count++;
|
|
|
|
init_simh();
|
|
|
|
saved_PC = 0100;
|
|
|
|
randomize_registers_all_values();
|
|
REGFILE[0][0] = REGFILE[0][1] = v1;
|
|
REGFILE[1][0] = REGFILE[1][1] = v2;
|
|
|
|
init_stack_registers();
|
|
|
|
struct mem_t mem[1] = {
|
|
{ 0100, instr }
|
|
};
|
|
|
|
PSW = 0;
|
|
|
|
json_t *obj = generate_test(instr, &id, mem, 1);
|
|
if (obj)
|
|
json_array_append_new(out, obj);
|
|
}
|
|
|
|
printf("%.2f%% %f \r", count * 100 / (double)total, total / (double)count * (time(NULL) - start));
|
|
fflush(NULL);
|
|
}
|
|
}
|
|
dump_json(filename, out);
|
|
}
|
|
|
|
void emit_bit_instructions()
|
|
{
|
|
printf("bit instructions\n");
|
|
const char *const filename = "pdp1170-valtest-BIT-INSTRUCTIONS.json";
|
|
if (file_exist(filename))
|
|
return;
|
|
int id = 0;
|
|
json_t *out = json_array();
|
|
int count = 0;
|
|
int total = n_test_values * n_test_values * 3 * 2 * 2;
|
|
time_t start = time(NULL);
|
|
for(int word=0; word<2; word++) {
|
|
for(int group=3; group<6; group++) {
|
|
uint16_t instr = (word << 15) | (group << 12) | (1 << 6 /* src=R1 */);
|
|
|
|
for(int v1=0; v1<n_test_values; v1++) {
|
|
for(int v2=0; v2<n_test_values; v2++) {
|
|
for(int psw_val=0; psw_val<2; psw_val++) {
|
|
count++;
|
|
|
|
init_simh();
|
|
|
|
saved_PC = 0100;
|
|
|
|
randomize_registers_all_values();
|
|
REGFILE[0][0] = REGFILE[0][1] = v1;
|
|
REGFILE[1][0] = REGFILE[1][1] = v2;
|
|
|
|
init_stack_registers();
|
|
|
|
struct mem_t mem[1] = {
|
|
{ 0100, instr }
|
|
};
|
|
|
|
PSW = psw_val;
|
|
|
|
json_t *obj = generate_test(instr, &id, mem, 1);
|
|
if (obj)
|
|
json_array_append_new(out, obj);
|
|
}
|
|
}
|
|
|
|
printf("%.2f%% %f \r", count * 100 / (double)total, total / (double)count * (time(NULL) - start));
|
|
fflush(NULL);
|
|
}
|
|
}
|
|
}
|
|
dump_json(filename, out);
|
|
}
|
|
|
|
void produce_validation_tests()
|
|
{
|
|
srand(123); // for reproducability
|
|
|
|
generate_test_values();
|
|
|
|
emit_branch_instructions();
|
|
emit_condition_sets();
|
|
emit_add_sub_c();
|
|
emit_bit_instructions();
|
|
emit_cmp();
|
|
emit_add_double_oper_instr();
|
|
}
|