Compare commits

..

No commits in common. "valgen" and "master" have entirely different histories.

6 changed files with 8 additions and 977 deletions

View file

@ -94,7 +94,6 @@ if (NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "CMAKE_BUILD_TYPE is ${CMAKE_BUILD_TYPE}") message(STATUS "CMAKE_BUILD_TYPE is ${CMAKE_BUILD_TYPE}")
endif (NOT CMAKE_BUILD_TYPE) endif (NOT CMAKE_BUILD_TYPE)
endif () endif ()
set(CMAKE_BUILD_TYPE "RelWithDebInfo")
# SIMH_SYSTEM_ID: Roughly analogous to the autoconf system triple. Used (almost exclusively) # SIMH_SYSTEM_ID: Roughly analogous to the autoconf system triple. Used (almost exclusively)
# as part of the dependencies' top-level directory name. # as part of the dependencies' top-level directory name.

View file

@ -104,64 +104,3 @@ add_simulator(uc15
LABEL PDP11 LABEL PDP11
PKG_FAMILY pdp11_family PKG_FAMILY pdp11_family
TEST uc15) TEST uc15)
add_simulator(pdp11-validator-gen
SOURCES
test.c
pdp11_fp.c
pdp11_cpu.c
pdp11_dz.c
pdp11_cis.c
pdp11_lp.c
pdp11_rk.c
pdp11_rl.c
pdp11_rp.c
pdp11_rx.c
pdp11_stddev.c
pdp11_sys.c
pdp11_tc.c
pdp11_tm.c
pdp11_ts.c
pdp11_io.c
pdp11_rq.c
pdp11_tq.c
pdp11_pclk.c
pdp11_ry.c
pdp11_pt.c
pdp11_hk.c
pdp11_xq.c
pdp11_xu.c
pdp11_vh.c
pdp11_rh.c
pdp11_tu.c
pdp11_cpumod.c
pdp11_cr.c
pdp11_rf.c
pdp11_dl.c
pdp11_ta.c
pdp11_rc.c
pdp11_kg.c
pdp11_ke.c
pdp11_dc.c
pdp11_dmc.c
pdp11_kmc.c
pdp11_dup.c
pdp11_rs.c
pdp11_vt.c
pdp11_td.c
pdp11_io_lib.c
pdp11_rom.c
pdp11_ch.c
pdp11_dh.c
pdp11_ng.c
pdp11_daz.c
pdp11_tv.c
pdp11_mb.c
pdp11_rr.c
INCLUDES
${CMAKE_CURRENT_SOURCE_DIR}
DEFINES
VM_PDP11
LABEL PDP11
PKG_FAMILY pdp11_family
TEST pdp11)

View file

@ -279,44 +279,6 @@ typedef struct {
/* Global state */ /* Global state */
struct __mem_writes {
int32_t addr;
uint8_t data;
} *mem_writes;
int n_mem_writes = 0;
#define MAX_N_MEM_WRITES 512
void init_mem_writes()
{
mem_writes = (struct __mem_writes *)malloc(sizeof(struct __mem_writes) * MAX_N_MEM_WRITES);
}
void put_mem_write(uint8_t data, int32_t pa)
{
int i = 0;
int found = 0;
for(i=0; i<n_mem_writes; i++) {
if (mem_writes[i].addr == pa) {
mem_writes[i].data = data;
found = 1;
break;
}
}
if (found == 0) {
if (n_mem_writes >= MAX_N_MEM_WRITES) {
printf("MEMORY WRITES OVERFLOW a=%06o v=%06o\n", pa, data);
char *a = NULL;
*a = 123;
}
else {
//printf("write to a=%06o v=%06o\n", pa, data);
mem_writes[n_mem_writes].addr = pa;
mem_writes[n_mem_writes].data = data;
n_mem_writes++;
}
}
}
uint16 *M = NULL; /* memory */ uint16 *M = NULL; /* memory */
int32 REGFILE[6][2] = { {0} }; /* R0-R5, two sets */ int32 REGFILE[6][2] = { {0} }; /* R0-R5, two sets */
int32 STACKFILE[4] = { 0 }; /* SP, four modes */ int32 STACKFILE[4] = { 0 }; /* SP, four modes */
@ -871,7 +833,7 @@ else {
Check for traps or interrupts. If trap, locate the vector and check Check for traps or interrupts. If trap, locate the vector and check
for stop condition. If interrupt, locate the vector. for stop condition. If interrupt, locate the vector.
*/ */
int show = 0;
while (reason == 0) { while (reason == 0) {
int32 IR, srcspec, srcreg, dstspec, dstreg; int32 IR, srcspec, srcreg, dstspec, dstreg;
@ -893,9 +855,9 @@ while (reason == 0) {
STACKFILE[cm] = SP; STACKFILE[cm] = SP;
saved_PC = PC & 0177777; saved_PC = PC & 0177777;
pcq_r->qptr = pcq_p; /* update pc q ptr */ pcq_r->qptr = pcq_p; /* update pc q ptr */
//set_r_display (rs, cm); set_r_display (rs, cm);
//reason = sim_process_event (); /* process events */ reason = sim_process_event (); /* process events */
/* restore simh register contents into running variables */ /* restore simh register contents into running variables */
PC = saved_PC; PC = saved_PC;
@ -910,8 +872,7 @@ while (reason == 0) {
MMR0 = MMR0 | MMR0_IC; /* usually on */ MMR0 = MMR0 | MMR0_IC; /* usually on */
trap_req = calc_ints (ipl, trap_req); /* recalc int req */ trap_req = calc_ints (ipl, trap_req); /* recalc int req */
//continue; continue;
break;
} /* end if sim_interval */ } /* end if sim_interval */
if (trap_req) { /* check traps, ints */ if (trap_req) { /* check traps, ints */
@ -1095,11 +1056,8 @@ while (reason == 0) {
break; break;
} }
case 2: /* RTI */ case 2: /* RTI */
// show = 1;
src = ReadW (SP | dsenable); src = ReadW (SP | dsenable);
src2 = ReadW (((SP + 2) & 0177777) | dsenable); src2 = ReadW (((SP + 2) & 0177777) | dsenable);
// if (IR == 2)
// printf("> %06o %06o", src, src2);
STACKFILE[cm] = SP = (SP + 4) & 0177777; STACKFILE[cm] = SP = (SP + 4) & 0177777;
oldrs = rs; oldrs = rs;
put_PSW (src2, (cm != MD_KER)); /* store PSW, prot */ put_PSW (src2, (cm != MD_KER)); /* store PSW, prot */
@ -1112,14 +1070,11 @@ while (reason == 0) {
SP = STACKFILE[cm]; SP = STACKFILE[cm];
isenable = calc_is (cm); isenable = calc_is (cm);
dsenable = calc_ds (cm); dsenable = calc_ds (cm);
// printf("(%d)", trap_req);
trap_req = calc_ints (ipl, trap_req); trap_req = calc_ints (ipl, trap_req);
JMP_PC (src); JMP_PC (src);
if (CPUT (HAS_RTT) && tbit && /* RTT impl? */ if (CPUT (HAS_RTT) && tbit && /* RTT impl? */
(IR == 000002)) (IR == 000002))
setTRAP (TRAP_TRC); /* RTI immed trap */ setTRAP (TRAP_TRC); /* RTI immed trap */
// if (IR == 2)
// printf("| %06o %06o <%d|%d>", PC, get_PSW(), trap_req, TRAP_INT);
break; break;
case 7: /* MFPT */ case 7: /* MFPT */
if (CPUT (HAS_MFPT)) /* implemented? */ if (CPUT (HAS_MFPT)) /* implemented? */
@ -2478,8 +2433,6 @@ while (reason == 0) {
else setTRAP (TRAP_ILL); else setTRAP (TRAP_ILL);
break; /* end case 017 */ break; /* end case 017 */
} /* end switch op */ } /* end switch op */
if (trap_req == 0 || trap_req == 2048 /* RTI/RTT? */)
break;
} /* end main loop */ } /* end main loop */
/* Simulation halted */ /* Simulation halted */
@ -2489,8 +2442,6 @@ for (i = 0; i < 6; i++)
REGFILE[i][rs] = R[i]; REGFILE[i][rs] = R[i];
STACKFILE[cm] = SP; STACKFILE[cm] = SP;
saved_PC = PC & 0177777; saved_PC = PC & 0177777;
//if (show)
//printf("%06o %06o\n", saved_PC, PSW);
pcq_r->qptr = pcq_p; /* update pc q ptr */ pcq_r->qptr = pcq_p; /* update pc q ptr */
set_r_display (rs, cm); set_r_display (rs, cm);
return reason; return reason;
@ -2824,7 +2775,6 @@ if ((va & 1) && CPUT (HAS_ODD)) { /* odd address? */
ABORT (TRAP_ODD); ABORT (TRAP_ODD);
} }
pa = relocW (va); /* relocate */ pa = relocW (va); /* relocate */
if (BPT_SUMM_WR && if (BPT_SUMM_WR &&
(sim_brk_test (va & 0177777, BPT_WRVIR) || (sim_brk_test (va & 0177777, BPT_WRVIR) ||
sim_brk_test (pa, BPT_WRPHY))) /* write breakpoint? */ sim_brk_test (pa, BPT_WRPHY))) /* write breakpoint? */
@ -2863,17 +2813,9 @@ if (BPT_SUMM_WR &&
PWriteW (data, pa); PWriteW (data, pa);
} }
void reset_mem_writes()
{
n_mem_writes = 0;
}
void PWriteW (int32 data, int32 pa) void PWriteW (int32 data, int32 pa)
{ {
if (ADDR_IS_MEM (pa)) { /* memory address? */ if (ADDR_IS_MEM (pa)) { /* memory address? */
put_mem_write(data, pa);
put_mem_write(data >> 8, pa + 1);
WrMemW (pa, data); WrMemW (pa, data);
return; return;
} }
@ -2891,8 +2833,6 @@ return;
void PWriteB (int32 data, int32 pa) void PWriteB (int32 data, int32 pa)
{ {
if (ADDR_IS_MEM (pa)) { /* memory address? */ if (ADDR_IS_MEM (pa)) { /* memory address? */
put_mem_write(data, pa);
WrMemB (pa, data); WrMemB (pa, data);
return; return;
} }

View file

@ -1,841 +0,0 @@
#include <jansson.h>
#include <stdio.h>
#include <time.h>
#include <sys/stat.h>
#include "pdp11_defs.h"
#include "pdp11_cpumod.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;
extern t_stat reason;
extern int32 MMR1;
extern int32 MMR2;
extern CPUTAB cpu_tab[];
struct __mem_writes {
int32_t addr;
uint8_t data;
};
extern struct __mem_writes *mem_writes;
extern int n_mem_writes;
extern void reset_mem_writes();
extern void init_mem_writes();
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;
}
void put_mem(json_t *memory_i, struct mem_t *mem, int n_mem)
{
for(size_t i=0; i<n_mem; i++) {
char buffer1[16];
char buffer2[16];
json_t *put_mem_i_0 = json_object();
json_t *put_mem_i_1 = json_object();
PWriteW(mem[i].value, mem[i].addr);
if (mem[i].addr & 1)
printf("FAIL\n");
sprintf(buffer1, "%06o", mem[i].addr);
json_object_set(put_mem_i_0, buffer1, json_integer(mem[i].value & 255));
json_array_append_new(memory_i, put_mem_i_0);
sprintf(buffer2, "%06o", mem[i].addr + 1);
json_object_set(put_mem_i_1, buffer2, json_integer(mem[i].value >> 8));
json_array_append_new(memory_i, put_mem_i_1);
}
}
json_t *generate_test(int *const id, struct mem_t *mem, size_t n_mem, int run_n_instructions, struct mem_t *setup_mem, int n_setup_mem)
{
json_t *before = json_object();
json_object_set(before, "PC", json_integer(saved_PC));
json_object_set(before, "run-n-instructions", json_integer(run_n_instructions));
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_object_set(before, "mmr1", json_integer(MMR1));
json_object_set(before, "mmr2", json_integer(MMR2));
json_t *memory_i = json_array();
put_mem(memory_i, mem, n_mem);
if (setup_mem)
put_mem(memory_i, setup_mem, n_setup_mem);
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 = 0;
for(int k=0; k<run_n_instructions; k++)
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_object_set(after, "mmr1", json_integer(MMR1));
json_object_set(after, "mmr2", json_integer(MMR2));
json_t *memory_o = json_array();
for(int i=0; i<n_mem_writes; i++) {
char buffer[16];
sprintf(buffer, "%06o", mem_writes[i].addr);
json_t *get_mem = json_object();
json_object_set(get_mem, buffer, json_integer(mem_writes[i].data));
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;
reset_mem_writes();
reason = 0;
cpu_model = MOD_1170;
cpu_type = 1u << cpu_model;
cpu_opt = cpu_tab[cpu_model].std;
cpu_set_bus (cpu_opt);
}
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 produce_set_register(const uint16_t instr, const uint16_t psw, int *const id, json_t *const out)
{
for(int v1=0; v1<n_test_values; v1++) {
for(int v2=0; v2<n_test_values; v2++) {
init_simh();
saved_PC = 0100;
randomize_registers_all_values();
REGFILE[0][0] = REGFILE[0][1] = test_values[v1];
REGFILE[1][0] = REGFILE[1][1] = test_values[v2];
init_stack_registers();
struct mem_t mem[1] = {
{ 0100, instr }
};
PSW = psw;
json_t *obj = generate_test(id, mem, 1, 1, NULL, 0);
if (obj)
json_array_append_new(out, obj);
}
}
}
void produce_set_register_indirect(const uint16_t instr, const uint16_t psw, int *const id, json_t *const out)
{
if (((instr >> 3) & 7) != 1 || (instr & 7) != 1) {
printf("Not an R1 target!");
return;
}
for(int v1=0; v1<n_test_values; v1++) {
for(int v2=0; v2<n_test_values; v2++) {
init_simh();
saved_PC = 0100;
randomize_registers_all_values();
REGFILE[0][0] = REGFILE[0][1] = test_values[v1];
REGFILE[1][0] = REGFILE[1][1] = 01002;
init_stack_registers();
struct mem_t mem[2] = {
{ 0100, instr },
{ 01002, test_values[v2] }
};
PSW = psw;
json_t *obj = generate_test(id, mem, 2, 1, NULL, 0);
if (obj)
json_array_append_new(out, obj);
}
}
}
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++) { // word/byte
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(&id, mem, 1, 1, NULL, 0);
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(&id, mem, 1, 1, NULL, 0);
if (obj)
json_array_append_new(out, obj);
}
}
dump_json(filename, out);
}
void emit_add_sub_c()
{
printf("ADD/SUB instructions\n");
const char *const filename = "pdp1170-valtest-ADD_SUB.json";
if (file_exist(filename))
return;
int id = 0;
json_t *out = json_array();
for(int group=0; group<2; group++) {
for(int word=0; word<2; word++) {
uint16_t instr = (6 << 12 /* instr */) | (word << 15 /* ADD/SUB */) | (1 << 6 /* src=R1 */);
produce_set_register(instr, 0, &id, out);
}
}
dump_json(filename, out);
}
void emit_single_operand_instructions()
{
printf("single operand instructions\n");
int groups[] = { 00001, 00003, 00050, 01050, 00051, 01051, 00052, 01052, 00053, 01053, 00054, 01054, 00055, 01055, 00056, 01056, 00057, 01057, 00060, 01060, 00061, 01061, 00062, 01062, 00063, 01063, 00067, -1 };
for(int dst=0; dst<2; dst++) {
for(int group=0; group<27; group++) {
char filename[128] = { 0 };
sprintf(filename, "pdp1170-valtest-SINGLE_OPERAND-%o-%d.json", groups[group], dst);
if (file_exist(filename))
continue;
printf("%s \r", filename);
fflush(NULL);
int id = 0;
json_t *out = json_array();
uint16_t instr = 0;
if (groups[group] == 00001 || dst == 1) // JMP can't jump to a register
instr = (groups[group] << 6) | 010; // (R0)
else
instr = (groups[group] << 6) | 001; // R0
for(int v1=0; v1<n_test_values; v1++) {
for(int psw_val=0; psw_val<2; psw_val++) {
init_simh();
saved_PC = 0100;
randomize_registers_all_values();
init_stack_registers();
PSW = psw_val;
struct mem_t mem[2] = {
{ 0100, instr },
{ 02000, test_values[v1] }
};
json_t *obj = NULL;
if (groups[group] == 00001 || dst == 1) {
REGFILE[0][0] = REGFILE[0][1] = 02000;
obj = generate_test(&id, mem, 2, 1, NULL, 0);
}
else {
REGFILE[0][0] = REGFILE[0][1] = test_values[v1];
obj = generate_test(&id, mem, 1, 1, NULL, 0);
}
if (obj)
json_array_append_new(out, obj);
}
}
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();
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 psw_val=0; psw_val<2; psw_val++)
produce_set_register(instr, psw_val, &id, out);
}
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();
for(int group=0; group<8; group++) {
uint16_t instr = (7 << 12) | (group << 9 /* instr */) | (2 << 6 /* src=R2 */);
if (group == 5 || group == 6)
continue;
produce_set_register(instr, 0, &id, out);
}
dump_json(filename, out);
}
void emit_bit_instructions()
{
printf("bit instructions\n");
for(int group=3; group<6; group++) {
char filename[64];
sprintf(filename, "pdp1170-valtest-BIT-INSTRUCTIONS-%d.json", group);
if (file_exist(filename))
continue;
int id = 0;
json_t *out = json_array();
for(int word=0; word<2; word++) {
uint16_t instr = (word << 15) | (group << 12) | (1 << 6 /* src=R1 */);
for(int psw_val=0; psw_val<2; psw_val++) {
produce_set_register(instr, psw_val, &id, out);
if (group == 4 || group == 5) {
uint16_t instr2 = (word << 15) | (group << 12) | 011 /* target is '(R1)' */;
produce_set_register_indirect(instr2, psw_val, &id, out);
}
}
}
dump_json(filename, out);
}
}
void emit_misc_operations()
{
printf("misc instructions\n");
const char *const filename = "pdp1170-valtest-MISC.json";
if (file_exist(filename) == 0) {
int id = 0;
json_t *out = json_array();
int groups[] = { 2 /* RTI */, 6 /* RTT */ };
for(int group=0; group<2; group++) {
for(int psw_val=0; psw_val<65536; psw_val++) {
if ((psw_val & 0174377) != psw_val)
continue;
uint16_t instr = groups[group];
init_simh();
saved_PC = 0100;
randomize_registers_all_values();
STACKFILE[0] = STACKFILE[1] = STACKFILE[2] = STACKFILE[3] = 07774;
struct mem_t mem[3] = {
{ 0100, instr },
{ 07776, 01234 },
{ 07774, 06420 }
};
PSW = psw_val;
//if (instr == 2)
// printf("PSW=%06o, ", PSW);
json_t *obj = generate_test(&id, mem, 3, 1, NULL, 0);
if (obj)
json_array_append_new(out, obj);
}
}
for(int group=0; group<3; group++) {
uint16_t instr = 0;
if (group == 0)
instr = 0100 | 010; // JMP (R0)
else if (group == 1)
instr = 04000 | 0110; // JSR R1,(R0)
else if (group == 2)
instr = 0200 | 01; // RTS (R1)
produce_set_register(instr, 0, &id, out);
}
dump_json(filename, out);
}
// TRAP
const char *const filename2 = "pdp1170-valtest-MISC2.json";
if (file_exist(filename2) == 0) {
int id = 0;
json_t *out = json_array();
uint16_t instr = 0104420; // TRAP #020
init_simh();
saved_PC = 0100;
randomize_registers_all_values();
init_stack_registers();
struct mem_t mem[1] = {
{ 0100, instr }
};
PSW = 012;
json_t *obj = generate_test(&id, mem, 1, 1, NULL, 0);
if (obj)
json_array_append_new(out, obj);
dump_json(filename2, out);
}
}
/*
MOV #0172340,R0
MOV #0000,(R0) ; 000000-020000 (K,I) will be mapped to physical address 00000
MOV #0172300,R0
MOV #077006,(R0) ; 000000-020000 full access
MOV #0172366,R0
MOV #0400,(R0) ; 060000-080000 (K,D) will be mapped to physical address 04000
MOV #0172326,R0
MOV #077006,(R0) ; 000000-020000 full access
MOV #0177572,R0
BIS #513,(R0) ; enable MMU & trap
MOV #0100,R0 ; JMP to main code
JMP (R0)
*/
#define MMU_SETUP_PROG \
{ 0500, 012700 }, \
{ 0502, 0172340 }, \
{ 0504, 012710 }, \
{ 0506, 0000000 }, \
{ 0510, 012700 }, \
{ 0512, 0172300 }, \
{ 0514, 012710 }, \
{ 0516, 0077006 }, \
{ 0520, 012700 }, \
{ 0522, 0172366 }, \
{ 0524, 012710 }, \
{ 0526, 0000400 }, \
{ 0530, 012700 }, \
{ 0532, 0172326 }, \
{ 0534, 012710 }, \
{ 0536, 0077006 }, \
{ 0540, 012700 }, \
{ 0542, 0177572 }, \
{ 0544, 052710 }, \
{ 0546, 0000513 }, \
{ 0550, 012700 }, \
{ 0552, 0000100 }, \
{ 0554, 000110 }, \
{ 0004, 02300 }, /* trap address */ \
{ 0006, 0123456 }, /* PSW */ \
{ 0034, 02500 }, /* trap address */ \
{ 0036, 0177777 }, /* PSW */ \
void emit_mov()
{
printf("mov instructions\n");
struct mem_t setup[27] = {
MMU_SETUP_PROG
};
for(int d_i=0; d_i<2; d_i++) {
char filename[64];
sprintf(filename, "pdp1170-valtest-MOV_%d.json", d_i);
if (file_exist(filename) == 0) {
int id = 0;
json_t *out = json_array();
{
init_simh();
saved_PC = 0100;
randomize_registers_all_values();
init_stack_registers();
PSW = 0;
struct mem_t mem[7] = {
{ 0100, 012705 }, // MOV #01234,R5
{ 0102, 001234 },
{ 0104, 010525 }, // MOV R5,(R5)+
};
json_t *obj = generate_test(&id, mem, 3, 2, NULL, 0);
if (obj)
json_array_append_new(out, obj);
}
uint16_t test_vals[] = { 0, 127, 128, 255, 256, 65535 };
for(int i=0; i<24; i++) {
init_simh();
saved_PC = 0100;
randomize_registers_all_values();
init_stack_registers();
PSW = 0;
struct mem_t mem[7] = {
{ 0100, 012700 },
{ 0102, test_vals[i % 6] },
{ 0104, 012701 },
{ 0106, 02000 },
{ 0110, 0110051 }, // @-(R1)
{ 01776, 03000 },
{ 03000, 0 }
};
int set = i / 6;
if (set == 1)
mem[4].value = 0010051;
else if (set == 2) {
mem[4].value = 0010031; // @(R1)+
mem[5].addr = 02000;
}
else if (set == 3) {
mem[4].value = 0110031; // @(R1)+
mem[5].addr = 02000;
}
json_t *obj = generate_test(&id, mem, 7, 3, NULL, 0);
if (obj)
json_array_append_new(out, obj);
}
for(int i=0; i<12; i++) {
init_simh();
saved_PC = 0100;
randomize_registers_all_values();
init_stack_registers();
PSW = 0;
struct mem_t mem[7] = {
{ 0100, 012700 },
{ 0102, test_vals[i % 6] },
{ 0104, 012701 },
{ 0106, 02000 },
{ 0110, 0110061 }, // @(R1)
{ 0112, 0000004 },
{ 02004, 012344 },
};
int set = i / 6;
if (set == 1) {
mem[5].value = 0100004;
mem[6].addr = 0102004;
}
json_t *obj = generate_test(&id, mem, 7, 3, NULL, 0);
if (obj)
json_array_append_new(out, obj);
}
{
init_simh();
saved_PC = 0100;
randomize_registers_all_values();
init_stack_registers();
PSW = 0;
struct mem_t mem[7] = {
{ 0100, 012701 },
{ 0102, 001000 },
{ 0104, 012771 }, // @X(R7)
{ 0106, 002222 },
{ 0110, 001000 },
{ 02000, 012344 },
};
json_t *obj = generate_test(&id, mem, 6, 2, NULL, 0);
if (obj)
json_array_append_new(out, obj);
}
for(int i=0; i<48; i++) {
init_simh();
randomize_registers_all_values();
init_stack_registers();
PSW = 0;
struct mem_t mem[5] = {
{ 0100, 012700 }, // MOV #random,(R0)
{ 0102, test_vals[i % 6] },
{ 0104, 012701 }, // MOV #0, (R1)
{ 0106, 0 },
{ 0110, 0110001 }, // MOV R0, R1
};
int set = i / 6;
if (set == 1) // R1
mem[4].value = 0010001; // MOVB R0,R1
else if (set == 2) { // (R1)
mem[3].value = 0060000; // MOV #060000,R1
mem[4].value = 0110011; // MOV R0,(R1)
}
else if (set == 3) { // (R1)
mem[3].value = 0060000; // MOV #060000,R1
mem[4].value = 0010011; // MOVB R0,(R1)
}
else if (set == 4) { // (R1)+
mem[3].value = 0060000; // MOV #060000,R1
mem[4].value = 0110021;
}
else if (set == 5) { // (R1)+
mem[3].value = 0060000;
mem[4].value = 0010021;
}
else if (set == 6) { // -(R1)
mem[3].value = 0060000;
mem[4].value = 0110041;
}
else if (set == 7) { // -(R1)
mem[3].value = 0060000;
mem[4].value = 0010041;
}
json_t *obj = NULL;
if (d_i == 1) {
saved_PC = 0500;
obj = generate_test(&id, mem, 5, 3 + 12, setup, 27);
}
else {
saved_PC = 0100;
obj = generate_test(&id, mem, 5, 3, NULL, 0);
}
if (obj)
json_array_append_new(out, obj);
}
dump_json(filename, out);
}
}
}
void produce_validation_tests()
{
srand(123); // for reproducability
init_mem_writes();
generate_test_values();
emit_branch_instructions(); // conditional_branch_instructions*
emit_condition_sets(); // condition_code_operations*
emit_add_double_oper_instr(); // additional_double_operand_instructions*
emit_add_sub_c(); // double_operand_instructions*, single_operand_instructions*
emit_single_operand_instructions(); // single_operand_instructions
emit_bit_instructions(); // double_operand_instructions
emit_cmp(); // double_operand_instructions
emit_misc_operations();
emit_mov();
// TODO:
// - double_operand_instructions: MOV
// - single_operand_instructions: MTPS, MFPI, MFPD, MTPI, MTPD, MFPS
// ...
}

View file

@ -102,7 +102,6 @@ function(build_simcore _targ)
simh_regexp simh_regexp
os_features os_features
thread_lib thread_lib
jansson
) )
# Ensure that sim_rev.h picks up .git-commit-id.h if the git command is # Ensure that sim_rev.h picks up .git-commit-id.h if the git command is
@ -358,7 +357,7 @@ function(add_unit_test _targ)
simh_executable_template(${UNIT_TARGET} "${ARGN}") simh_executable_template(${UNIT_TARGET} "${ARGN}")
cmake_parse_arguments(SIMH "FEATURE_INT64;FEATURE_FULL64;BUILDROMS;FEATURE_VIDEO,FEATURE_DISPLAY" cmake_parse_arguments(SIMH "FEATURE_INT64;FEATURE_FULL64;BUILDROMS;FEATURE_VIDEO,FEATURE_DISPLAY"
"SOURCE_DIR;LABEL" "SOURCE_DIR;LABEL"
"DEFINES;INCLUDES;SOURCES" "DEFINES;INCLUDES;SOURCES"
${ARGN}) ${ARGN})
target_link_libraries(${UNIT_TARGET} PUBLIC unittest) target_link_libraries(${UNIT_TARGET} PUBLIC unittest)

11
scp.c
View file

@ -2917,7 +2917,7 @@ if (!sim_quiet) {
printf ("\n"); printf ("\n");
show_version (stdout, NULL, NULL, 0, NULL); show_version (stdout, NULL, NULL, 0, NULL);
} }
//sim_timer_precalibrate_execution_rate (); sim_timer_precalibrate_execution_rate ();
show_version (stdnul, NULL, NULL, 1, NULL); /* Quietly set SIM_OSTYPE */ show_version (stdnul, NULL, NULL, 1, NULL); /* Quietly set SIM_OSTYPE */
#if defined (HAVE_PCRE_H) #if defined (HAVE_PCRE_H)
setenv ("SIM_REGEX_TYPE", "PCRE", 1); /* Publish regex type */ setenv ("SIM_REGEX_TYPE", "PCRE", 1); /* Publish regex type */
@ -2971,10 +2971,8 @@ if (docmdp) {
} }
if (SCPE_BARE_STATUS(stat) == SCPE_OPENERR) /* didn't exist/can't open? */ if (SCPE_BARE_STATUS(stat) == SCPE_OPENERR) /* didn't exist/can't open? */
stat = SCPE_OK; stat = SCPE_OK;
extern void produce_validation_tests(); if (SCPE_BARE_STATUS(stat) != SCPE_EXIT)
produce_validation_tests(); process_stdin_commands (SCPE_BARE_STATUS(stat), argv, FALSE);
//if (SCPE_BARE_STATUS(stat) != SCPE_EXIT)
// process_stdin_commands (SCPE_BARE_STATUS(stat), argv, FALSE);
cleanup_and_exit: cleanup_and_exit:
@ -7790,7 +7788,6 @@ t_stat ssh_break_one (FILE *st, int32 flg, t_addr lo, int32 cnt, CONST char *apt
{ {
if (!sim_brk_types) if (!sim_brk_types)
return sim_messagef (SCPE_NOFNC, "No breakpoint support in this simulator\n"); return sim_messagef (SCPE_NOFNC, "No breakpoint support in this simulator\n");
printf("%d %d %d %s\n", flg, lo, cnt, aptr);
switch (flg) { switch (flg) {
case SSH_ST: case SSH_ST:
@ -12499,8 +12496,6 @@ t_stat sim_brk_set (t_addr loc, int32 sw, int32 ncnt, CONST char *act)
{ {
BRKTAB *bp; BRKTAB *bp;
printf("sim_brk_set: %d, %d, %d, %s\n", loc, sw, ncnt, act);
if ((sw == 0) || (sw == BRK_TYP_DYN_STEPOVER)) if ((sw == 0) || (sw == BRK_TYP_DYN_STEPOVER))
sw |= sim_brk_dflt; sw |= sim_brk_dflt;
if (~sim_brk_types & sw) { if (~sim_brk_types & sw) {