#define VERSION "0.3" // see ChangeLog

// This prototype is straight out of the GNU Readline Library manual
/* A static variable for holding the line. */
static char *line_read = (char *)NULL;
char * rl_gets (char * p);

// bitmasks for manipulating parts of words (unsigned int int)
#define WORD_MASK       0777777777777ULL // entire 36 bit word
#define OP_MASK         0770000000000ULL // opcode
#define U_MASK          0007777700000ULL // U address
#define V_MASK          0000000077777ULL // V address
#define BIT34           0200000000000ULL // bit 34
#define BIT35           0400000000000ULL // sign bit
#define BIT36          01000000000000ULL // carry bit
#define BIT63 01000000000000000000000ULL // borrow bit

// bitmasks for manipulating address counter registers
// (which are all of type unsigned int)
#define J_MASK                 070000    // bits u_15 to u_12
#define N_MASK                 007777    // bits u_11 to u_0
#define VHIGH_MASK             077600    // bits v_14 to v_7

// function prototpyes
void halt(int sig_num);
void catch_int(int sig_num);
void run(void);
void pstate(void);
void cycle(void);
void decode(void);
void io_close(int sig_num);
unsigned long long readaddr(unsigned int addr);
void writeaddr(unsigned int addr, unsigned long long val,
	       unsigned long long bitflag);
void io_open(void);
void nextop(void);
void add(void);
void sub(void);
int is_a(unsigned int addr);
int is_q(unsigned int addr);
void dx(void);
void sx(void);
void cleara(void);
void shifta1(void);
void shifta(unsigned int count);
void shiftq1(void);
void shiftq(unsigned int count);
void mul(void);
void div(void);
void repeat_cycle(void);
void inc_pak(unsigned int *pak);
void dec_pak(unsigned int *pak);
void split_pcr(void);
void help(void);
void prog_int(int sig_num);
void paddr(unsigned int addr);
void diss(unsigned int addr);

// control registers
unsigned int pak;        // program address counter (15 bits)
#define PAK_START 040000 // starting address at power on
unsigned long long pcr;  // program control register (36 bits, curr. instr.)
unsigned int mcr;        // main control register (6 most sig. bits of pcr)
unsigned int uak;        // "u" operand, (15 next most sig. bits of pcr)
unsigned int vak;        // "v" operand, (15 least sig. bits of pcr)
unsigned int sar;        // storage address register (15 bits)
unsigned int sk;         // shift counter (7 bits)

// This is not part of architecture, but is used by emulator 
// stepwise debugger during RPjnw repeated instructions.
// we need this because the real machine's microcoded operation 
// for RPjnw hijacks the PAK to use it to count the repeats, so
// it is impossible for the stepwise debugger to rely on PAK to point
// to (current instruction + 1) as it should
unsigned int pak_repeat = 0; // "true" program counter when RPjnw in effect
unsigned int j_rpt = 0; // address modification scheme

// arithmetic registers
unsigned long long al; // accumulator left half (most sig. 36 bits)
unsigned long long ar; // accumulator right half (least sig. 36 bits)
unsigned long long x;  // 36 bit exchange register
unsigned long long q;  // quotient register

// 72 bit register to hold double length extensions of X register this
// is temp storage for emulator, not part of architecture mnemonic:
// atl/r -- accumulator temporary left/right.  We need this temp
// register to ease the adding of 72 bit quantities, since C99 does
// not support unsigned int > 64 bits.
unsigned long long atl;	
unsigned long long atr;

// storage registers
#define MAX_CORE 3*4096 // 3 banks of 4096 words
#define MAX_DRUM 4*4096 // 4 banks of 4096 words
unsigned long long mcs[MAX_CORE]; // core
unsigned long long md[MAX_DRUM]; // drum

// parts of words.  Again, these aren't part of the architecture, but
// it is easier to split up the PCR into parts when the instruction is
// fetched via nextop() rather than form them as needed in each case:
// case statement in decode()
unsigned int j;
unsigned int k;
unsigned int n;
unsigned int w;

// manually selectable switches, 1 = on, 0 = off
// ms[0] and mj[0] are unused
unsigned int ms[4]; // stops
unsigned int mj[4]; // jumps

// special addresses for jumps, subroutine calls,
// and program interrupt
unsigned int f1 = 000000;  // start with f1 switch pointing to core
unsigned int f2 = 000001;  // core address
unsigned int f3 = 000002;  // core address

// flags for emulator use only
int run_flag = 0;       // 1 = run, 0 = halt
int vhigh_flag = 0;     // 1 = vhigh address modification, 0 = none
int a71borrow_flag = 0; // 1 = borrow in MSB of accumulator
int repeat_flag = 0;    // 1 = repeat opcode RPjnw (075) in effect
                        // 2 = first step of repeat loop
int prog_int_flag = 0;  // 1 = program interrupt in effect
int pak_flag = 0;       // 1 = use pak_repeat as debugger's program counter

// emulator breakpoint array:  bp[i] = 1 if an emulator breakpoint
// is set at octal address i
int bp[077777];

// instruction encoding table used in disassembly
char opc[64][6] = {
  "??", "??",   "??",   "??",   "??",   "??",   "??",   "??",
  "??", "TPuv", "TMuv", "TNuv", "IPxx", "TUuv", "TVuv", "EF-v",
  "??", "RAuv", "LTjkv", "RSuv", "??", "??", "??", "CCuv",
  "??", "SPuk", "SAuk", "SNuk", "SSuk", "ATuv", "STuv", "RJuv",
  "??", "IJuv", "TJuv", "EJuv", "QJuv", "MJjv", "SJuv", "ZJuv",
  "??", "QTuv", "QAuv", "QSuv", "LAuk", "LQuk", "MSjv", "PS--",
  "??", "PR-v", "??",   "PUjv", "??",   "??",   "??",   "??",
  "??", "MPuv", "MAuv", "DVuv", "SFuv", "RPjnw", "ERjv", "EWjv" };
