
/*
	GIER simulator

	(C) Copyright 2001 by Mogens Kjaer


   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "GIER.h"


/*
	Declaration of registers
*/

GIERword BUS;
GIERword LI;
GIERword LI_drum;
GIERword OR;
GIERword MD;
GIERword H;
GIERword MQ;
GIERword AC;
unsigned short AD0,AD1,IN,OT,AD2,SR,TK,BL,BY,BS,TD,BT,TBA,TG,TA;
int ind_ka,ind_kb,switch_k0,aarhus_mode;
void (*Mode)();
void (*drumsave_Mode)();
int MA,drumsave_MA;
int h,b,c;
int spild;
int debug;
FILE *debug_fh;
int YE_wait;
int TO_error=0;
int TR_error=0;

int running;
int normal_start_pressed=0;
int normal_stop_pressed=0;
int normal_singlestep_pressed=0;
int mikrotempi_start_pressed=0;
int mikrotempi_stop_pressed=0;
int HP_button_pressed=0;
int sound_enabled;
extern void Mode1();
extern unsigned char remove_parity(unsigned char);
extern unsigned char flx2a(unsigned char, int *);
extern void printword(GIERword);
extern void GIER_stop();
extern void GIER_start();
extern void interface_update_all();
extern void interface_run();

GIERword Ferrit[1024];
GIERword *Tromle;
GIERword *Buffer=NULL;
GIERword *BDisk[MAXBDISKS];
int BDisk_tracksize[MAXBDISKS];
int BDisk_present[MAXBDISKS];
int BDisk_size[MAXBDISKS];
btapeblock *BTape[MAXBTAPES];
int BTape_len[MAXBTAPES];
int BTape_current[MAXBTAPES];
GIERword BTape_status[MAXBTAPES];
GIERword *BCarr[CARROUSELREELS][CARROUSELBLOCKS];
int Tromle_size;
int track0_open, track1_31_open;
int testmode;
int sound_enabled;
int interface_check_interval=INTERFACE_CHECK_INTERVAL;
int disk_status=0;
int disk_cylinder=0;
GIERword last_disk_count=0;
GIERword disk_count=0;
double drum_count=0;
int drum_running=0;
int gier_clock=460850;
double drum_clock=232.753;
double drum_speed=49.6;
/* double drum_clock=228; */
int drum_wait=0;
int drum_mode=0; /* 0 read, 1 write */
int drum_address=0;
int drum_cell_count=0;
long statistics[128];
long long timing_statistics[1024];
char *opcodes[]=
  {"qq", "zq", "ar", "sr", "an", "sn", "ac", "sc",
   "mb", "ab", "mt", "mk", "ml", "dk", "dl", "nk",
   "nl", "hr", "tl", "ck", "cl", "gr", "ga", "gt",
   "tk", "ca", "gm", "pm", "xr", "gi", "ps", "pp",
   "pa", "pt", "hk", "pi", "is", "it", "cm", "bt",
   "ns", "nt", "gp", "nc", "il", "us", "gg", "gc",
   "pc", "bs", "hs", "vy", "lk", "sk", "gk", "vk",
   "hv", "zj", "sy", "ly", "hh", "gs", "zl", "ud"};

/*
	Typewriter, reader, and punch stuff
*/

int typewriter_nchars=0;
char typewriter_char_table[TYPEWRITER_TABLE_SIZE];
int reader_nchars=0, reader_offset=READER_TAPE_OFFSET;
char reader_char_table[READER_TAPE_WINDOW+READER_TAPE_OFFSET];
int reader_parity_error;
int selected_out[5];

char *last_filename = NULL;

/*
   	Demo mode:
*/

FILE *demofile;
/*
   Demo mode:

  0:	off
  1:	parsing commands
  2:	read next command at demosleep
  3:	wait for keyboard output to be demochar
  4:	wait for keyboard in input mode
  5:	wait for stop (ZQ)
*/
int demomode;
char demoline[100];
int demosleep;
int demochar;

/*
	Bufferdisks:
*/

bdisktype bdisktypes[MAXBDISKTYPES]=
{
  {"Not present", 0, 0},
  {"CDC 854", 600, 2030},
  {"MK 001", 600, 4095},
  {NULL, 0, 0}
};


static GIERword MASKINTAL(double x)
{
  GIERword w;

  fprintf(debug_fh, " Maskintal %lg: ", x);
  if(x<0.0)
  {
    x = -x*((double)ONE0);
    w = (-(GIERword) x)&ONE0_39;
  }
  else
  {
    x=x*((double)ONE0);
    w = (GIERword) x;
  }
  printword(w);
  return(w);
}

GIERword FLYDENDE(double x)
{
  GIERword w;
  int exponent;
  double mantissa;

  exponent=0;
  if(x==0.0)
    w=0;
  else if(x<0.0)
  {
    mantissa= -x;
    while(mantissa>=2.0) {mantissa *= 0.5; exponent++;}
    while(mantissa<1.0) {mantissa *= 2.0; exponent--;}
    w=(((GIERword)(exponent&1023))<<SHIFT9) |
           ((-((GIERword)(mantissa*ONE11)))&ONE10_39);
  }
  else
  {
    mantissa=x;
    while(mantissa>=2.0) {mantissa *= 0.5; exponent++;}
    while(mantissa<1.0) {mantissa *= 2.0; exponent--;}
    w=(((GIERword)(exponent&1023))<<SHIFT9) |
           (((GIERword)(mantissa*ONE11))&ONE10_39);
  }

  if(debug&DEBUGflydende)
  {
    fprintf(debug_fh, "FLYDENDE: %.12g: ",x);
    printword(w);
  }
  return w;
}

void demo1()
{
  /* Test of fixed point addition and relative addressing */
  Ferrit[10] = Opcode(Op_AR) | Smark | r_relative | Address1(3);		/* [10]  ARS r+3 */
  Ferrit[11] = Opcode(Op_AR) | r_relative | Address1(3);			/* [11]  AR  r+3 */
  Ferrit[12] = Opcode(Op_GR) | Address1(15) | Right(Opcode(Op_ZQ));		/* [12]  GR  15,ZQ 0 */
  Ferrit[13] = 12<<SHIFT39;							/* [13]  QQ  12.39 */
  Ferrit[14] = 7<<SHIFT39;							/* [14]  QQ  7.39 */
}

void demo2()
{
  /* Test of floating point multiplication */
  Ferrit[10] = Opcode(Op_AR) | Smark | r_relative | Address1(3) | Fmark;	/* [10]  ARFS r+3 */
  Ferrit[11] = Opcode(Op_MK) | r_relative | Address1(3) | Fmark;		/* [11]  MKF  r+3 */
  Ferrit[12] = Opcode(Op_GR) | Address1(15) | Right(Opcode(Op_ZQ)) | Fmark;	/* [12]  GRF  15,ZQ 0 */
  Ferrit[13] = FLYDENDE(3.14);
  Ferrit[14] = FLYDENDE(2.0);
}

void demo3()
{
  /* Move value */
  Ferrit[10] = Opcode(Op_AR) | Smark | Address1(20);				/* [10]  ARS 20 */
  Ferrit[11] = Opcode(Op_GR) | Address1(25) | Right(Opcode(Op_ZQ));		/* [11]  GR 25,ZQ 0 */
  Ferrit[20] = 127<<SHIFT39;							/* [20]  QQ 127.39 */
}

void demo4()
{
  /* Timing test. Remember, the rest of the core is filled with QQ's */
  Ferrit[10] = Opcode(Op_BT) | Address1(511) | Address2(-1);			/* [  10] BT 511 t-1 */
  Ferrit[11] = Opcode(Op_HV) | Address1(14);					/* [  11] HV 14 */
  Ferrit[12] = Opcode(Op_ZQ);							/* [  12] ZQ 0 */
  Ferrit[13] = Opcode(Op_PA) | Address1(10) | Address2(511);			/* [  13] PA 10 t+511 */
}

void demo5()
{
  /* Test of shift operation */
  Ferrit[10] = Opcode(Op_PM) | Address1(16) | Xmark;				/* [10] PM 16 X */
  Ferrit[11] = Opcode(Op_CK) | Address1(-1) | Ind_oper(IND_I) 
                            | Ind_addr1(IND_O) | Ind_addr2(IND_A);		/* [11] CK -1 IOA */
  Ferrit[12] = Opcode(Op_GR) | Address1(100) | Address2(1) | Ind_oper(IND_M)
                            | Ind_addr1(IND_O) | Ind_addr2(IND_A);		/* [12] GR 100 t+1 MOA */
  Ferrit[13] = Opcode(Op_BT) | Address1(40) | Address2(-1);			/* [13] BT 40 t-1 */
  Ferrit[14] = Opcode(Op_HV) | Address1(11);					/* [14] HV 11 */
  Ferrit[15] = Opcode(Op_ZQ);							/* [15] ZQ */
  Ferrit[16] = ((GIERword)1)<<SHIFT1;						/* [16] QQ 1.1 */
}

void demo6()
{
  /* Test of machine number multiplication */
  Ferrit[10] = Opcode(Op_PM) | Address1(14);					/* [10] PM 14 */
  Ferrit[11] = Opcode(Op_MK) | Address1(15) | Smark;				/* [11] MKS 15 */
  Ferrit[12] = Opcode(Op_GR) | Address1(16);					/* [12] GR 16 */
  Ferrit[13] = Opcode(Op_ZQ);							/* [13] ZQ */
  Ferrit[14] = MASKINTAL(0.3);
  Ferrit[15] = MASKINTAL(0.17);
  Ferrit[16] = 0;
}

void demo7()
{
  /* Test of long multiplication */
  Ferrit[10] = Opcode(Op_PM) | Address1(15);					/* [10] PM 15 */
  Ferrit[11] = Opcode(Op_ML) | Address1(16) | Smark;				/* [11] MLS 16 */
  Ferrit[12] = Opcode(Op_GR) | Address1(17);					/* [12] GR 17 */
  Ferrit[13] = Opcode(Op_GM) | Address1(18);					/* [13] GM 18 */
  Ferrit[14] = Opcode(Op_ZQ);							/* [14] ZQ */
  Ferrit[15] = (100ULL)<<SHIFT39;
  Ferrit[16] = (1000ULL)<<SHIFT39;
  Ferrit[17] = 0;
  Ferrit[18] = 0;
}

void demo8()
{
  /* Test of long mult and div */
  Ferrit[10] = Opcode(Op_PM) | Address1(16);					/* [10] PM 16 */
  Ferrit[11] = Opcode(Op_ML) | Address1(17) | Smark;				/* [11] MLS 17 */
  Ferrit[12] = Opcode(Op_DL) | Address1(18);					/* [12] DL 18 */
  Ferrit[13] = Opcode(Op_GR) | Address1(19);					/* [13] GR 19 */
  Ferrit[14] = Opcode(Op_GM) | Address1(20);					/* [14] GM 20 */
  Ferrit[15] = Opcode(Op_ZQ);							/* [15] ZQ */
  Ferrit[16] = (10000ULL)<<SHIFT39;
  Ferrit[17] = (1000ULL)<<SHIFT39;
  Ferrit[18] = (101ULL)<<SHIFT39;
  Ferrit[19] = 0;
  Ferrit[20] = 0;
}

void demo9()
{
  /* Test of short divide */
  Ferrit[10] = Opcode(Op_AR) | Smark | Address1(15);				/* [10] ARS 15 */
  Ferrit[11] = Opcode(Op_DK) | Address1(16);					/* [11] DK 16 */
  Ferrit[12] = Opcode(Op_GR) | Address1(17);					/* [12] GR 17 */
  Ferrit[13] = Opcode(Op_GM) | Address1(18);					/* [13] GM 18 */
  Ferrit[14] = Opcode(Op_ZQ);							/* [14] ZQ */
  Ferrit[15] = MASKINTAL(0.21242321);
  Ferrit[16] = MASKINTAL(0.3329739);
  Ferrit[17] = 0;
  Ferrit[18] = 0;
}

void demo10()
{
  /* Test of normalize */
  Ferrit[10] = Opcode(Op_AR) | Address1(14) | Smark;				/* [10] ARS 14 */
  Ferrit[11] = Opcode(Op_NK) | Address1(0) | Fmark;				/* [11] NKF 0 */
  Ferrit[12] = Opcode(Op_GR) | Address1(15) | Fmark;				/* [12] GRF 15 */
  Ferrit[13] = Opcode(Op_ZQ);
  Ferrit[14] = MASKINTAL(-0.123);
  Ferrit[15] = 0;
}

void demo11()
{
  /* Test of converting a float to a fixed number */
  Ferrit[10] = Opcode(Op_AR) | Address1(14) | Smark | Fmark;			/* [10] ARFS 14 */
  Ferrit[11] = Opcode(Op_TK) | Address1(10) | Fmark;				/* [11] TKF 10 */
  Ferrit[12] = Opcode(Op_GR) | Address1(15);					/* [12] GR 15 */
  Ferrit[13] = Opcode(Op_ZQ);
  Ferrit[14] = FLYDENDE(-0.123);
  Ferrit[15] = 0;
}

void demo12()
{
  /* Test of floating point multiply */
  Ferrit[ 0] = Opcode(Op_ZQ);							/* [ 0] ZQ */
  Ferrit[10] = Opcode(Op_AR) | Address1(14) | Smark | Fmark;			/* [10] ARFS 14 */
  Ferrit[11] = Opcode(Op_MK) | Address1(14) | Fmark;				/* [11] MKF 14 */
  Ferrit[12] = Opcode(Op_GR) | Address1(99) | Address2(1) | Fmark;		/* [12] GRF 99 t+1 */
  Ferrit[13] = Opcode(Op_HV) | Address1(11);					/* [13] HV 11 */
  Ferrit[14] = FLYDENDE(10.0);
  Ferrit[100] = 0;
}

void demo13()
{
  /* test of floating point overflow. Jumps to cell 0 */
  Ferrit[ 0] = Opcode(Op_ZQ);							/* [ 0] ZQ */
  Ferrit[10] = Opcode(Op_AR) | Address1(14) | Smark | Fmark;			/* [10] ARFS 14 */
  Ferrit[11] = Opcode(Op_AR) | Address1(14) | Fmark;				/* [11] ARF 14 */
  Ferrit[12] = Opcode(Op_GR) | Address1(99) | Address2(1) | Fmark;		/* [12] GRF 99 t+1 */
  Ferrit[13] = Opcode(Op_HV) | Address1(11);					/* [13] HV 11 */
  Ferrit[14] = FLYDENDE(1.0e153);
  Ferrit[100] = 0;
}

void demo14()
{
  /* Square root calculation sequence */
  Ferrit[  0] = Opcode(Op_ZQ);							/* [ 0] ZQ */
  Ferrit[ 10] = Opcode(Op_AR) | Address1(20) |  Smark | Fmark;			/* [10] ARFS 20 */
  Ferrit[ 11] = Opcode(Op_HS) | Address1(140);					/* [11] HS 140 */
  Ferrit[ 12] = Opcode(Op_GR) | Address1(21) | Fmark;				/* [12] GRF 21 */
  Ferrit[ 13] = Opcode(Op_HV) | Address1(10);					/* [13] HV 10 */
  Ferrit[ 20] = FLYDENDE(0.001);
  Ferrit[128] = Opcode(Op_PA) | Address1(8) | r_relative | Address2(4);		/* [128] PA r+8 +4 */
  Ferrit[129] = Opcode(Op_GR) | Address1(9) | r_relative |
                Right(Opcode(Op_NK) | Address1(1) | r_relative);		/* [129] GR r+9, NK r+1 */
  Ferrit[130] = Opcode(Op_SR) | Address1(0) | Smark | Dmark;			/* [130] SRS 0 D */
  Ferrit[131] = Opcode(Op_TK) | Address1(-11) |
                Right(Opcode(Op_GT) | Address1(1) | r_relative);		/* [131] TK -11, GT r+1 */
  Ferrit[132] = Opcode(Op_AR) | Address1(6) | r_relative | Smark |
                Right(Opcode(Op_TK) | Address1(0));				/* [132] ARS r+6, TK 0 */
  Ferrit[133] = Opcode(Op_GR) | Address1(6) | r_relative |
                Right(Opcode(Op_AR) | Address1(5) | r_relative | Smark); 	/* [133] GR r+6, ARS r+5 */
  Ferrit[134] = Opcode(Op_DK) | Address1(5) | r_relative |
                Right(Opcode(Op_AR) | Address1(5) | r_relative);		/* [134] DK r+5, AR r+5 */
  Ferrit[135] = Opcode(Op_TK) | Address1(-1) |
                Right(Opcode(Op_IT) | Address1(-1));				/* [135] TK -1, IT -1 */
  Ferrit[136] = Opcode(Op_BT) | Address1(4) |
                Right(Opcode(Op_HV) | Address1(-3) | r_relative);		/* [136] BT 4, HV r-3 */
  Ferrit[137] = Opcode(Op_HR) | Address1(1) | s_relative;			/* [137] HR s+1 */
  Ferrit[138] = Opcode(Op_QQ);							/* [138] QQ 0 */
  Ferrit[139] = Opcode(Op_QQ);							/* [139] QQ 0 */
  Ferrit[140] = Opcode(Op_GR) | Address1(-2) | r_relative | Xmark;		/* [140] GR r-2 X */
  Ferrit[141] = Opcode(Op_AR) | Address1(2) | Dmark;				/* [141] AR 2 D */
  Ferrit[142] = Opcode(Op_TK) | Address1(-1) |
                Right(Opcode(Op_GA) | Address1(5) | r_relative);		/* [142] TK -1, GA r+5 */
  Ferrit[143] = Opcode(Op_TK) | Address1(10) |
                Right(Opcode(Op_CK) | Address1(-19));				/* [143] TK 10, CK -19 */
  Ferrit[144] = Opcode(Op_GT) | Address1(1) | r_relative |
                Right(Opcode(Op_AR) | Address1(-6) | r_relative | Smark);	/* [144] GT r+1, ARS r-6 */
  Ferrit[145] = Opcode(Op_TK) | Address1(9) |
                Right(Opcode(Op_TK) | Address1(1));				/* [145] TK 9, TK 1 */
  Ferrit[146] = Opcode(Op_HS) | Address1(-18) | r_relative;			/* [146] HS r-18 */
  Ferrit[147] = Opcode(Op_NK) | Address1(0) | Fmark |
                Right(Opcode(Op_HR) | Address1(1) | s_relative);		/* [147] NKF 0, HR s+1 */
}

void demo15()
{
  /* Test of unknown operation */
  Ferrit[10] = Opcode(Op_IL) | Address1(123);					/* [10]  IL 123 */
}

void demo16()
{
  /* Test of endless indirect addressing */
  Ferrit[10] = Opcode(Op_AR) | Address1(12) | Indirmark;			/* [10]  AR (12) */
  Ferrit[11] = Opcode(Op_ZQ);							/* [11]  ZQ 0 */
  Ferrit[12] = Opcode(Op_QQ) | Address1(13) | Indirmark;			/* [12]  QQ (13) */
  Ferrit[13] = Opcode(Op_QQ) | Address1(12) | Indirmark;			/* [13]  QQ (12) */
}

void demo17()
{
  /* Test of typewriter */
  Ferrit[10] = Opcode(Op_VY) | Address1(17);
  Ferrit[11] = Opcode(Op_SY) | Address1(60) |
               Right(Opcode(Op_SY) | Address1(55));
  Ferrit[12] = Opcode(Op_SY) | Address1(57) |
               Right(Opcode(Op_SY) | Address1(53));
  Ferrit[13] = Opcode(Op_SY) | Address1(41) |
               Right(Opcode(Op_SY) | Address1(58));
  Ferrit[14] = Opcode(Op_SY) | Address1(59) |
               Right(Opcode(Op_SY) | Address1(64));
  Ferrit[15] = Opcode(Op_ZQ) | Address1(0);
  Ferrit[16] = Opcode(Op_HV) | Address1(11);
}

void demo18()
{
  /* Read from typewriter */
  Ferrit[10] = Opcode(Op_VY) | Address1(17);
  Ferrit[11] = Opcode(Op_LY) | Address1(20) |
               Right(Opcode(Op_HV) | Address1(11));
}

void demo19()
{
  /* Copy paper tape. Stop on Stop Code */
  Ferrit[10] = Opcode(Op_VY) | Address1(16);
  Ferrit[11] = Opcode(Op_LY) | Address1(20) |
               Right(Opcode(Op_GA) | Address1(14));
  Ferrit[12] = Opcode(Op_NC) | Address1(11) |
               Right(Opcode(Op_HV) | Address1(14));
  Ferrit[12] = Opcode(Op_HV) | Address1(14);
  Ferrit[13] = Opcode(Op_ZQ) | 
               Right(Opcode(Op_HV) | Address1(11));
  Ferrit[14] = Opcode(Op_SY)|Right(Opcode(Op_HV)|Address1(11));
}

void demo20()
{
  /*

  GIER test program B7.

  Testprogram no. 7. Topsøes test of the floating point operations: AR F, SR F, MK F and DK F.

  The testprogram operates in 6000 cycles. In each cycle two random, floating point
  numbers, a and b, are generated by means of the subroutines RAND-1 and RAND-2. The four
  floating point operations are then carried out on the numbers a and b, and the
  four results are added (as fixed points numbers) to four sum cells.
  After 6000 cycles a line is printed on the typewriter, containing the number 6000 and
  the four sum cells in octal notation. The four sum cells are then
  cleared and 6000 new cycles are calculated, etc. If KB=1 the program will stop
  after 6000 cycles, and can be repeated by pressing the NORMAL START button.

  The correct output is (only the numbers):

  6000  35271407753020  36242706607000  66042725657530  15577777733744
  6000  35271407753020  36242706607000  66042725657530  15577777733744
  etc.
  test of:    add.            sub.            mult.          div.

  Calculation of 6000 cycles takes about 35 sec. The value of 6000 is stored
  in cell 114 as an integer in pos. 39. It may be changed if required.
  If KA is set to 1, output is obtained after each cycle.

  The program is stored from cell 41 to 136. The first instruction to be
  executed is zq LKB.

  */

  Ferrit[10] = Opcode(Op_HV) | Address1(41);

  Ferrit[41] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_K) | Ind_addr2(IND_B);
  Ferrit[42] = Opcode(Op_VY) | Address1(16) | Right(Opcode(Op_HV) | r_relative | Address1(+4));
  Ferrit[43] = Opcode(Op_QQ) | Address1(0);
  Ferrit[44] = Opcode(Op_QQ) | Address1(0);
  Ferrit[45] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_K) | Ind_addr2(IND_B);
  Ferrit[46] = Opcode(Op_GR) | Smark | r_relative | Address1(71);
  Ferrit[47] = Opcode(Op_GR) | Smark | r_relative | Address1(71);
  Ferrit[48] = Opcode(Op_GR) | Smark | r_relative | Address1(71);
  Ferrit[49] = Opcode(Op_GR) | Smark | r_relative | Address1(71);
  Ferrit[50] = Opcode(Op_HV) | r_relative | Address1(19);
  Ferrit[51] = Opcode(Op_QQ) | Address1(0);
  Ferrit[52] = Opcode(Op_QQ) | Address1(0);
  Ferrit[53] = Opcode(Op_QQ) | Ind_oper(IND_I) | Ind_addr1(IND_Z) | Ind_addr2(IND_A);
  Ferrit[54] = Opcode(Op_GC) | Smark | s_relative | Address1(9) | Address2(+320);
  Ferrit[55] = Opcode(Op_PI) | Address2(-65);
  Ferrit[56] = Opcode(Op_AR) | Smark | r_relative | Address1(-2) | Right(Opcode(Op_GR) | r_relative | Address1(-13));
  Ferrit[57] = Opcode(Op_DL) | Smark | r_relative | Address1(-14) | Right(Opcode(Op_TK) | Address1(20));
  Ferrit[58] = Opcode(Op_PI) | Address1(64) | Ind_oper(IND_N) | Ind_addr1(IND_Z) | Address2(-65);
  Ferrit[59] = Opcode(Op_HV) | r_relative | Address1(3) | Ind_oper(IND_N) | Ind_addr1(IND_Z);
  Ferrit[60] = Opcode(Op_HV) | r_relative | Address1(2) | Ind_oper(IND_N) | Ind_addr1(IND_T) | Ind_addr2(IND_B);
  Ferrit[61] = Opcode(Op_SY) | Address1(16) | Right(Opcode(Op_HV) | r_relative | Address1(2));
  Ferrit[62] = Opcode(Op_GT) | r_relative | Right(Opcode(Op_SY));
  Ferrit[63] = Opcode(Op_GM) | r_relative | Address1(-11) | Right(Opcode(Op_PM) | r_relative | Address1(-20));
  Ferrit[64] = Opcode(Op_DL) | Smark | r_relative | Address1(-11) | Right(Opcode(Op_GR) | r_relative | Address1(-21));
  Ferrit[65] = Opcode(Op_HR) | s_relative | Address1(2) | Ind_oper(IND_L) | Ind_addr1(IND_Z);
  Ferrit[66] = Opcode(Op_PM) | r_relative | Address1(-14) | Right(Opcode(Op_HV) | r_relative | Address1(-9));
  Ferrit[67] = Opcode(Op_QQ) | Address2(+256);
  Ferrit[68] = Opcode(Op_QQ) | Ind_oper(IND_I) | Ind_addr2(IND_B);
  Ferrit[69] = Opcode(Op_GR) | Smark | r_relative | Address1(-25);
  Ferrit[70] = Opcode(Op_AR) | Smark | r_relative | Address1(39) | Right(Opcode(Op_GR) | r_relative | Address1(65));
  Ferrit[71] = Opcode(Op_GR) | Smark | r_relative | Address1(44);
  Ferrit[72] = Opcode(Op_PP) | Address1(2) | Right(Opcode(Op_PP) | p_relative | Address1(-1));
  Ferrit[73] = Opcode(Op_GR) | Smark | p_relative | Address1(121) | Right(Opcode(Op_HS) | r_relative | Address1(51));
  Ferrit[74] = Opcode(Op_QQ) | Address1(20);
  Ferrit[75] = Opcode(Op_SR) | Address1(10) | Dmark;
  Ferrit[76] = Opcode(Op_GA) | p_relative | Address1(121) | Right(Opcode(Op_HS) | r_relative | Address1(52));
  Ferrit[77] = Opcode(Op_TK) | Address1(2) | Ind_oper(IND_I) | Ind_addr1(IND_T) | Ind_addr2(IND_A);
  Ferrit[78] = Opcode(Op_CK) | Address1(-6) | Right(Opcode(Op_TL) | Address1(-6));
  Ferrit[79] = Opcode(Op_AC) | p_relative | Address1(121) | Right(Opcode(Op_AR) | Smark | r_relative | Address1(-12));
  Ferrit[80] = Opcode(Op_TK) | Address1(1) | Ind_oper(IND_L) | Ind_addr1(IND_T) | Ind_addr2(IND_A);
  Ferrit[81] = Opcode(Op_AC) | p_relative | Address1(121);
  Ferrit[82] = Opcode(Op_BS) | p_relative | Right(Opcode(Op_HH) | r_relative | Address1(-10));
  Ferrit[83] = Opcode(Op_PP) | Address1(4) | Right(Opcode(Op_PP) | p_relative | Address1(-1));
  Ferrit[84] = Opcode(Op_AR) | Smark | r_relative | Address1(37) | Right(Opcode(Op_UD) | p_relative | Address1(110)) | Fmark;
  Ferrit[85] = Opcode(Op_GR) | r_relative | Address1(38) | Fmark;
  Ferrit[86] = Opcode(Op_AR) | Smark | r_relative | Address1(37) | Right(Opcode(Op_AC) | p_relative | Address1(117));
  Ferrit[87] = Opcode(Op_BS) | p_relative | Right(Opcode(Op_HH) | r_relative | Address1(-4));
  Ferrit[88] = Opcode(Op_HS) | Smark | r_relative | Address1(5) | Xmark | Ind_oper(IND_L) | Ind_addr1(IND_K) | Ind_addr2(IND_A) | Address2(52);
  Ferrit[89] = Opcode(Op_AR) | Smark | r_relative | Address1(-21) | Right(Opcode(Op_AR) | r_relative | Address1(+26));
  Ferrit[90] = Opcode(Op_GR) | r_relative | Address1(25) | Right(Opcode(Op_SR) | r_relative | Address1(24));
  Ferrit[91] = Opcode(Op_HV) | r_relative | Address1(-19) | Ind_oper(IND_L) | Ind_addr1(IND_T);
  Ferrit[92] = Opcode(Op_PS) | Smark | r_relative | Address1(43);
  Ferrit[93] = Opcode(Op_SY) | Address1(64) | Right(Opcode(Op_AR) | Smark | r_relative | Address1(22));
  Ferrit[94] = Opcode(Op_HS) | r_relative | Address1(-39) | Xmark | Address2(59);
  Ferrit[95] = Opcode(Op_QQ) | Address1(256) | Address2(-144);
  Ferrit[96] = Opcode(Op_SY) | Right(Opcode(Op_SY));
  Ferrit[97] = Opcode(Op_PP) | Address1(4) | Right(Opcode(Op_PP) | p_relative | Address1(-1));
  Ferrit[98] = Opcode(Op_AR) | Smark | p_relative | Address1(117) | Right(Opcode(Op_TL) | Address1(-10));
  Ferrit[99] = Opcode(Op_GA) | r_relative | Address1(17) | Right(Opcode(Op_SR) | r_relative | Address1(17));
  Ferrit[100] = Opcode(Op_TL) | Address1(3) | Right(Opcode(Op_CA));
  Ferrit[101] = Opcode(Op_SY) | Address1(16) | Right(Opcode(Op_HV) | r_relative | Address1(2));
  Ferrit[102] = Opcode(Op_GA) | r_relative | Address1(14) | Right(Opcode(Op_SY) | Indirmark | r_relative | Address1(14));
  Ferrit[103] = Opcode(Op_BT) | Address1(13) | Address2(-1);
  Ferrit[104] = Opcode(Op_HV) | r_relative | Address1(-5);
  Ferrit[105] = Opcode(Op_PA) | Smark | r_relative | Address1(-2) | Xmark | Address2(13);
  Ferrit[106] = Opcode(Op_SY) | Right(Opcode(Op_SY));
  Ferrit[107] = Opcode(Op_BS) | p_relative | Right(Opcode(Op_HH) | r_relative | Address1(-10));
  Ferrit[108] = Opcode(Op_HR) | s_relative | Address1(1);
  Ferrit[109] = Opcode(Op_BS) | p_relative | Address1(104) | Vmark | Address2(-333);
  Ferrit[110] = Opcode(Op_DK) | r_relative | Address1(11) | Fmark;
  Ferrit[111] = Opcode(Op_MK) | r_relative | Address1(11) | Fmark;
  Ferrit[112] = Opcode(Op_SR) | r_relative | Address1(10) | Fmark;
  Ferrit[113] = Opcode(Op_AR) | r_relative | Address1(9) | Fmark;
  Ferrit[114] = Opcode(Op_QQ) | Indirmark | s_relative | Xmark | Vmark | Ind_oper(IND_L) | Ind_addr1(IND_T);
  Ferrit[115] = Opcode(Op_QQ);
  Ferrit[116] = Opcode(Op_QQ);
  Ferrit[117] = Opcode(Op_QQ);
  Ferrit[118] = Opcode(Op_QQ);
  Ferrit[119] = Opcode(Op_QQ);
  Ferrit[120] = Opcode(Op_QQ);
  Ferrit[121] = Opcode(Op_QQ);
  Ferrit[122] = Opcode(Op_QQ);
  Ferrit[123] = Opcode(Op_QQ);
  Ferrit[124] = Opcode(Op_HS) | r_relative | Address1(4) | Address2(44);
  Ferrit[125] = Opcode(Op_XR) | Right(Opcode(Op_MK) | Smark | s_relative | Address1(1));
  Ferrit[126] = Opcode(Op_MB) | Address1(511) | Dmark;
  Ferrit[127] = Opcode(Op_HR) | s_relative | Address1(2);
  Ferrit[128] = Opcode(Op_PM) | r_relative | Address1(7) | Right(Opcode(Op_ML) | Smark | r_relative | Address1(5));
  Ferrit[129] = Opcode(Op_TK) | Address1(8) | Right(Opcode(Op_GM) | r_relative | Address1(6));
  Ferrit[130] = Opcode(Op_AR) | r_relative | Address1(5);
  Ferrit[131] = Opcode(Op_SR) | r_relative | Address1(3) | Ind_oper(IND_L) | Ind_addr1(IND_O);
  Ferrit[132] = Opcode(Op_GR) | r_relative | Address1(3) | Right(Opcode(Op_HR) | s_relative | Address1(1));
  Ferrit[133] = Opcode(Op_GT) | Smark | p_relative | Right(Opcode(Op_DL) | Smark | r_relative | Address1(434));
  Ferrit[134] = Opcode(Op_UD) | Smark | Indirmark | p_relative | Address1(511) | Right(Opcode(Op_PC) | Address1(-1));
  Ferrit[135] = Opcode(Op_QQ);
  Ferrit[136] = Opcode(Op_HV) | Address1(45);
}

void demo21()
{
  /* help3 channel 0 */

  Tromle[ 0] = Opcode(Op_QQ) | Right(Opcode(Op_HH)|Address1(23));
  Tromle[ 1] = Opcode(Op_IT) | Address1(960) | Right(Opcode(Op_PT) | Address1(1));
  Tromle[ 2] = Opcode(Op_QQ) | Right(Opcode(Op_GK) | Address1(2));
  Tromle[ 3] = Opcode(Op_VY) | Address1(529) | Right(Opcode(Op_HV) | Address1(6));
  Tromle[ 4] = Opcode(Op_AN) | Smark | s_relative | Address1(64) | Vmark | Ind_oper(IND_M) | Ind_addr1(IND_K) | Address2(479);
  Tromle[ 5] = Opcode(Op_ML) | p_relative | Address1(64) | Indirmark | Vmark | Dmark | Ind_oper(IND_L) | Ind_addr1(IND_P) | Ind_addr2(IND_B) | Address2(921);
  Tromle[ 6] = Opcode(Op_GI) | Address1(3) | Ind_oper(IND_I) | Ind_addr1(IND_P) | Ind_addr2(IND_C);
  Tromle[ 7] = Opcode(Op_GM) | Address1(6) | Ind_oper(IND_M) | Ind_addr1(IND_P) | Ind_addr2(IND_C);
  Tromle[ 8] = Opcode(Op_GS) | Address1(7) | Ind_oper(IND_I) | Ind_addr1(IND_O) | Ind_addr2(IND_B);
  Tromle[ 9] = Opcode(Op_GR) | Address1(8) | Ind_oper(IND_M) | Ind_addr1(IND_O) | Ind_addr2(IND_B);
  Tromle[10] = Opcode(Op_GA) | Address1(9) | Right(Opcode(Op_TL) | Address1(-39));
  Tromle[11] = Opcode(Op_PM) | s_relative | Ind_oper(IND_I) | Ind_addr1(IND_R) | Ind_addr2(IND_B);
  Tromle[12] = Opcode(Op_GR) | Address1(11) | Right(Opcode(Op_HR) | r_relative | Address1(1));
  Tromle[13] = Opcode(Op_GP) | Address1(12) | Right(Opcode(Op_AR) | Smark | Address1(4));
  Tromle[14] = Opcode(Op_SR) | Address1(-1) | Right(Opcode(Op_TK) | Address1(21));
  Tromle[15] = Opcode(Op_HV) | Address1(29) | Ind_oper(IND_N) | Ind_addr1(IND_Z);
  Tromle[16] = Opcode(Op_HV) | Address1(33) | Ind_oper(IND_N) | Ind_addr2(IND_A);
  Tromle[17] = Opcode(Op_AR) | Smark | Address1(5) | Right(Opcode(Op_PM) | Address1(-1));
  Tromle[18] = Opcode(Op_GA) | Address1(19) | Right(Opcode(Op_TK) | Address1(10));
  Tromle[19] = Opcode(Op_SY) | Address1(-1) | Right(Opcode(Op_CK) | Address1(-4));
  Tromle[20] = Opcode(Op_NC) | Right(Opcode(Op_HV) | Address1(18));
  Tromle[21] = Opcode(Op_LY) | Smark | Address1(-1) | Right(Opcode(Op_GM) | Address1(-1));
  Tromle[22] = Opcode(Op_BS) | Address1(1) | Right(Opcode(Op_HV) | Address1(27));
  Tromle[23] = Opcode(Op_GS) | Address1(10) | Right(Opcode(Op_VY) | Smark | Address1(528));
  Tromle[24] = Opcode(Op_TL) | Address1(-6) | Right(Opcode(Op_CA));
  Tromle[25] = Opcode(Op_LY) | r_relative | Address1(4) | Right(Opcode(Op_HS) | r_relative | Address1(-1));
  Tromle[26] = Opcode(Op_GM) | s_relative | Address1(3) | Ind_oper(IND_M) | Address2(-1);
  Tromle[27] = Opcode(Op_CA) | Right(Opcode(Op_HV) | Address1(33));
  Tromle[28] = Opcode(Op_NC) | Address1(17) | Right(Opcode(Op_HV) | Address1(17));
  Tromle[29] = Opcode(Op_VK) | Address1(960) | Right(Opcode(Op_IT) | Address1(1));
  Tromle[30] = Opcode(Op_VK) | Address1(294) | Right(Opcode(Op_IT) | Address1(40));
  Tromle[31] = Opcode(Op_SK) | Right(Opcode(Op_IT) | Address1(-1));
  Tromle[32] = Opcode(Op_NC) | Smark | Address1(24) | Right(Opcode(Op_HH) | Address1(29));
  Tromle[33] = Opcode(Op_VK) | Address1(960) | Right(Opcode(Op_VK) | Address1(1)) | Fmark;
  Tromle[34] = Opcode(Op_LK) | Address1(40) | Right(Opcode(Op_VK) | Smark | Address1(38));
  Tromle[35] = Opcode(Op_AR) | Address1(37) | Right(Opcode(Op_PA) | Address1(22));
  Tromle[36] = Opcode(Op_AR) | Address1(2) | Dmark | Ind_oper(IND_L) | Ind_addr2(IND_A);
  Tromle[37] = Opcode(Op_HV) | Indirmark | Address1(35) | Dmark | Ind_oper(IND_N) | Ind_addr2(IND_B) | Address2(1);
  Tromle[38] = Opcode(Op_HV) | Indirmark | Address1(17) | Dmark | Ind_oper(IND_N) | Ind_addr1(IND_Z) | Address2(-1);
  Tromle[39] = Opcode(Op_AR) | Smark | Address1(1) | Ind_oper(IND_I) | Ind_addr1(IND_Q) | Ind_addr2(IND_C);
  Tromle[79] = Fmark;
}

void demo22()
{
  /*
  	INDICATOR test

	GIER test B12.

	Before start KA, KB are set to 0, 1. The test is supplied with a number
	of loops, so if any error occurs, KA is set to one, and the program will
	run in the loop, where the error appeared. All stops indicate errors.
	Cellnumber is found by subtraction of one from the content of r1.

	I've changed two statements compared to the test as written.
  */

  Ferrit[ 10] = Opcode(Op_HV) | Address1(41);
  Ferrit[ 41] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_K) | Ind_addr2(IND_B);
  Ferrit[ 42] = Opcode(Op_GR) | Smark  | Address1(300);
  Ferrit[ 43] = Opcode(Op_PI) | Address1(-1);
  Ferrit[ 44] = Opcode(Op_GI) | Address1(300);
  Ferrit[ 45] = Opcode(Op_AR) | Smark  | Address1(300);
  Ferrit[ 46] = Opcode(Op_SR) | Address1(-1) | Dmark;
  Ferrit[ 47] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_Z);
  Ferrit[ 48] = Opcode(Op_HV) | Address1(43) | Ind_oper(IND_L) | Ind_addr1(IND_K) | Ind_addr2(IND_A);
  Ferrit[ 49] = Opcode(Op_PI);
  Ferrit[ 50] = Opcode(Op_GI) | Address1(300) | Ind_oper(IND_M) | Ind_addr1(IND_O) | Ind_addr2(IND_C);
  Ferrit[ 51] = Opcode(Op_AR) | Smark  | Address1(300);
  Ferrit[ 52] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_Z);
  Ferrit[ 53] = Opcode(Op_HV) | Address1(49) | Ind_oper(IND_L) | Ind_addr1(IND_K) | Ind_addr2(IND_A);
  Ferrit[ 54] = Opcode(Op_PI) | Address1(-1) | Address2(-2);
  Ferrit[ 55] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_R) | Ind_addr2(IND_B);
  Ferrit[ 56] = Opcode(Op_PI) | Address1(-2) | Address2(-3);
  Ferrit[ 57] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_R) | Ind_addr2(IND_A);
  Ferrit[ 58] = Opcode(Op_HV) | Address1(60) | Ind_oper(IND_L) | Ind_addr1(IND_R) | Ind_addr2(IND_C);
  Ferrit[ 59] = Opcode(Op_ZQ);
  Ferrit[ 60] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_O) | Ind_addr2(IND_A);
  Ferrit[ 61] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_O) | Ind_addr2(IND_B);
  Ferrit[ 62] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_T) | Ind_addr2(IND_A);
  Ferrit[ 63] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_T) | Ind_addr2(IND_B);
  Ferrit[ 64] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_P) | Ind_addr2(IND_A);
  Ferrit[ 65] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_P) | Ind_addr2(IND_B);
  Ferrit[ 66] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_Q) | Ind_addr2(IND_A);
  Ferrit[ 67] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_Q) | Ind_addr2(IND_B);
  Ferrit[ 68] = Opcode(Op_GI) | Address1(300) | Right(Opcode(Op_AR) | Smark  | Address1(300));
  Ferrit[ 69] = Opcode(Op_SR) | Address1(3) | Dmark;
  Ferrit[ 70] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_Z);
  Ferrit[ 71] = Opcode(Op_QQ) | Ind_oper(IND_M) | Ind_addr1(IND_O) | Ind_addr2(IND_C);
  Ferrit[ 72] = Opcode(Op_PP) | Smark  | Ind_oper(IND_I) | Ind_addr1(IND_R) | Ind_addr2(IND_B);
  Ferrit[ 73] = Opcode(Op_PP) | Smark  | Ind_oper(IND_I) | Ind_addr1(IND_R) | Ind_addr2(IND_A);
  Ferrit[ 74] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_R) | Ind_addr2(IND_B);
  Ferrit[ 75] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_R) | Ind_addr2(IND_A);
  Ferrit[ 76] = Opcode(Op_QQ) | Ind_oper(IND_M);
  Ferrit[ 77] = Opcode(Op_CK) | Address1(10) | Ind_oper(IND_I) | Ind_addr1(IND_R) | Ind_addr2(IND_B);
  Ferrit[ 78] = Opcode(Op_CK) | Address1(10) | Ind_oper(IND_I) | Ind_addr1(IND_R) | Ind_addr2(IND_A);
  Ferrit[ 79] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_R) | Ind_addr2(IND_A);
  Ferrit[ 80] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_R) | Ind_addr2(IND_B);
  Ferrit[ 81] = Opcode(Op_HV) | Address1(54) | Ind_oper(IND_L) | Ind_addr1(IND_K) | Ind_addr2(IND_A);
  Ferrit[ 82] = Opcode(Op_PI) | Address1(-4) | Address2(-5);
  Ferrit[ 83] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_Q) | Ind_addr2(IND_B);
  Ferrit[ 84] = Opcode(Op_PI) | Address1(-8) | Address2(-9);
  Ferrit[ 85] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_Q) | Ind_addr2(IND_A);
  Ferrit[ 86] = Opcode(Op_HV) | Address1(88) | Ind_oper(IND_L) | Ind_addr1(IND_Q) | Ind_addr2(IND_C);
  Ferrit[ 87] = Opcode(Op_ZQ);
  Ferrit[ 88] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_O) | Ind_addr2(IND_A);
  Ferrit[ 89] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_O) | Ind_addr2(IND_B);
  Ferrit[ 90] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_T) | Ind_addr2(IND_A);
  Ferrit[ 91] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_T) | Ind_addr2(IND_B);
  Ferrit[ 92] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_P) | Ind_addr2(IND_A);
  Ferrit[ 93] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_P) | Ind_addr2(IND_B);
  Ferrit[ 94] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_R) | Ind_addr2(IND_A);
  Ferrit[ 95] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_R) | Ind_addr2(IND_B);
  Ferrit[ 96] = Opcode(Op_GI) | Address1(300) | Right(Opcode(Op_AR) | Smark | Address1(300)); /* CHANGED - Was: gi, arn 300 */
  Ferrit[ 97] = Opcode(Op_SR) | Address1(15) | Dmark;
  Ferrit[ 98] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_Z);
  Ferrit[ 99] = Opcode(Op_GM) | Smark  | Address1(400) | Ind_oper(IND_I) | Ind_addr1(IND_Q) | Ind_addr2(IND_B);
  Ferrit[100] = Opcode(Op_GM) | Smark  | Address1(400) | Ind_oper(IND_I) | Ind_addr1(IND_Q) | Ind_addr2(IND_A);
  Ferrit[101] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_Q) | Ind_addr2(IND_B);
  Ferrit[102] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_Q) | Ind_addr2(IND_A);
  Ferrit[103] = Opcode(Op_QQ) | Ind_oper(IND_M);
  Ferrit[104] = Opcode(Op_TK) | Address1(2) | Ind_oper(IND_I) | Ind_addr1(IND_Q) | Ind_addr2(IND_B);
  Ferrit[105] = Opcode(Op_TK) | Address1(2) | Ind_oper(IND_I) | Ind_addr1(IND_Q) | Ind_addr2(IND_A);
  Ferrit[106] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_Q) | Ind_addr2(IND_B);
  Ferrit[107] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_Q) | Ind_addr2(IND_A);
  Ferrit[108] = Opcode(Op_HV) | Address1(82) | Ind_oper(IND_L) | Ind_addr1(IND_K) | Ind_addr2(IND_A);
  Ferrit[109] = Opcode(Op_PI) | Address1(-16) | Address2(-17);
  Ferrit[110] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_P) | Ind_addr2(IND_B);
  Ferrit[111] = Opcode(Op_PI) | Address1(-32) | Address2(-33);
  Ferrit[112] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_P) | Ind_addr2(IND_A);
  Ferrit[113] = Opcode(Op_HV) | Address1(115) | Ind_oper(IND_L) | Ind_addr1(IND_P) | Ind_addr2(IND_C);
  Ferrit[114] = Opcode(Op_ZQ);
  Ferrit[115] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_O) | Ind_addr2(IND_A);
  Ferrit[116] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_O) | Ind_addr2(IND_B);
  Ferrit[117] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_T) | Ind_addr2(IND_A);
  Ferrit[118] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_T) | Ind_addr2(IND_B);
  Ferrit[119] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_Q) | Ind_addr2(IND_A);
  Ferrit[120] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_Q) | Ind_addr2(IND_B);
  Ferrit[121] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_R) | Ind_addr2(IND_A);
  Ferrit[122] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_R) | Ind_addr2(IND_B);
  Ferrit[123] = Opcode(Op_GI) | Address1(300);
  Ferrit[124] = Opcode(Op_AR) | Smark  | Address1(300);
  Ferrit[125] = Opcode(Op_SR) | Address1(63) | Dmark;
  Ferrit[126] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_Z);
  Ferrit[127] = Opcode(Op_GM) | Smark  | Address1(400) | Ind_oper(IND_I) | Ind_addr1(IND_P) | Ind_addr2(IND_B);
  Ferrit[128] = Opcode(Op_GM) | Smark  | Address1(400) | Ind_oper(IND_I) | Ind_addr1(IND_P) | Ind_addr2(IND_A);
  Ferrit[129] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_P) | Ind_addr2(IND_B);
  Ferrit[130] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_P) | Ind_addr2(IND_A);
  Ferrit[131] = Opcode(Op_QQ) | Ind_oper(IND_M);
  Ferrit[132] = Opcode(Op_TL) | Address1(4) | Ind_oper(IND_I) | Ind_addr1(IND_P) | Ind_addr2(IND_B);
  Ferrit[133] = Opcode(Op_TL) | Address1(4) | Ind_oper(IND_I) | Ind_addr1(IND_P) | Ind_addr2(IND_A);
  Ferrit[134] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_P) | Ind_addr2(IND_B);
  Ferrit[135] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_P) | Ind_addr2(IND_A);
  Ferrit[136] = Opcode(Op_HV) | Address1(109) | Ind_oper(IND_L) | Ind_addr1(IND_K) | Ind_addr2(IND_A);
  Ferrit[137] = Opcode(Op_PI) | Address1(-64) | Address2(-65);
  Ferrit[138] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_T) | Ind_addr2(IND_B);
  Ferrit[139] = Opcode(Op_PI) | Address1(-128) | Address2(-129);
  Ferrit[140] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_T) | Ind_addr2(IND_A);
  Ferrit[141] = Opcode(Op_HV) | Address1(143) | Ind_oper(IND_L) | Ind_addr1(IND_T) | Ind_addr2(IND_C);
  Ferrit[142] = Opcode(Op_ZQ);
  Ferrit[143] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_O) | Ind_addr2(IND_A);
  Ferrit[144] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_O) | Ind_addr2(IND_B);
  Ferrit[145] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_T) | Ind_addr2(IND_A);
  Ferrit[146] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_T) | Ind_addr2(IND_B);
  Ferrit[147] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_P) | Ind_addr2(IND_A);
  Ferrit[148] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_P) | Ind_addr2(IND_B);
  Ferrit[149] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_Q) | Ind_addr2(IND_A);
  Ferrit[150] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_Q) | Ind_addr2(IND_B);
  Ferrit[151] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_R) | Ind_addr2(IND_A);
  Ferrit[152] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_R) | Ind_addr2(IND_B);
  Ferrit[153] = Opcode(Op_GI) | Address1(300);
  Ferrit[154] = Opcode(Op_AR) | Smark  | Address1(300);
  Ferrit[155] = Opcode(Op_SR) | Address1(255) | Dmark;
  Ferrit[156] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_Z);
  Ferrit[157] = Opcode(Op_QQ) | Smark  | Ind_oper(IND_I) | Ind_addr1(IND_T) | Ind_addr2(IND_B);
  Ferrit[158] = Opcode(Op_QQ) | Smark  | Ind_oper(IND_I) | Ind_addr1(IND_T) | Ind_addr2(IND_A);
  Ferrit[159] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_T) | Ind_addr2(IND_B);
  Ferrit[160] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_T) | Ind_addr2(IND_A);
  Ferrit[161] = Opcode(Op_AR) | Smark  | Address1(-1) | Dmark | Ind_oper(IND_I) | Ind_addr1(IND_T) | Ind_addr2(IND_B);
  Ferrit[162] = Opcode(Op_AR) | Smark  | Address1(-1) | Dmark | Ind_oper(IND_I) | Ind_addr1(IND_T) | Ind_addr2(IND_A);
  Ferrit[163] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_T) | Ind_addr2(IND_B);
  Ferrit[164] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_T) | Ind_addr2(IND_A);
  Ferrit[165] = Opcode(Op_HV) | Address1(137) | Ind_oper(IND_L) | Ind_addr1(IND_K) | Ind_addr2(IND_A);
  /* Ferrit[165] = Opcode(Op_ZQ); */
  Ferrit[166] = Opcode(Op_PI) | Address1(-256) | Address2(-257);
  Ferrit[167] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_O) | Ind_addr2(IND_B);
  Ferrit[168] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_Z) | Ind_addr2(IND_B);
  Ferrit[169] = Opcode(Op_PI) | Address1(-512) | Address2(+511); /* CHANGED - Was: pi -512 t-511  */
  Ferrit[170] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_O) | Ind_addr2(IND_A);
  Ferrit[171] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_Z) | Ind_addr2(IND_A);
  Ferrit[172] = Opcode(Op_HV) | Address1(174) | Ind_oper(IND_L) | Ind_addr1(IND_O) | Ind_addr2(IND_C);
  Ferrit[173] = Opcode(Op_ZQ);
  Ferrit[174] = Opcode(Op_HV) | Address1(176) | Ind_oper(IND_L) | Ind_addr1(IND_Z) | Ind_addr2(IND_C);
  Ferrit[175] = Opcode(Op_ZQ);
  Ferrit[176] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_T) | Ind_addr2(IND_A);
  Ferrit[177] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_T) | Ind_addr2(IND_B);
  Ferrit[178] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_P) | Ind_addr2(IND_A);
  Ferrit[179] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_P) | Ind_addr2(IND_B);
  Ferrit[180] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_Q) | Ind_addr2(IND_A);
  Ferrit[181] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_Q) | Ind_addr2(IND_B);
  Ferrit[182] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_R) | Ind_addr2(IND_A);
  Ferrit[183] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_R) | Ind_addr2(IND_B);
  Ferrit[184] = Opcode(Op_GI) | Address1(300);
  Ferrit[185] = Opcode(Op_AR) | Smark  | Address1(300);
  Ferrit[186] = Opcode(Op_SR) | Address1(-1) | Dmark;
  Ferrit[187] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_Z);
  Ferrit[188] = Opcode(Op_AR) | Smark  | Ind_oper(IND_I) | Ind_addr1(IND_O) | Ind_addr2(IND_B);
  Ferrit[189] = Opcode(Op_QQ) | Smark  | Ind_oper(IND_I) | Ind_addr1(IND_O) | Ind_addr2(IND_A);
  Ferrit[190] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_O) | Ind_addr2(IND_B);
  Ferrit[191] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_O) | Ind_addr2(IND_A);
  Ferrit[192] = Opcode(Op_AR) | Smark  | Address1(-1) | Dmark;
  Ferrit[193] = Opcode(Op_AR) | Address1(-512) | Dmark | Ind_oper(IND_I) | Ind_addr1(IND_O) | Ind_addr2(IND_B);
  Ferrit[194] = Opcode(Op_AR) | Address1(-512) | Dmark | Ind_oper(IND_I) | Ind_addr1(IND_O) | Ind_addr2(IND_A);
  Ferrit[195] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_O) | Ind_addr2(IND_B);
  Ferrit[196] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_O) | Ind_addr2(IND_A);
  Ferrit[197] = Opcode(Op_HV) | Address1(166) | Ind_oper(IND_L) | Ind_addr1(IND_K) | Ind_addr2(IND_A);
  Ferrit[198] = Opcode(Op_PI) | Address1(-1);
  Ferrit[199] = Opcode(Op_PI) | Address2(-1);
  Ferrit[200] = Opcode(Op_HV) | Address1(202) | Ind_oper(IND_L) | Ind_addr1(IND_Z) | Ind_addr2(IND_C);
  Ferrit[201] = Opcode(Op_ZQ);
  Ferrit[202] = Opcode(Op_HV) | Address1(204) | Ind_oper(IND_L) | Ind_addr1(IND_O) | Ind_addr2(IND_C);
  Ferrit[203] = Opcode(Op_ZQ);
  Ferrit[204] = Opcode(Op_HV) | Address1(206) | Ind_oper(IND_L) | Ind_addr1(IND_T) | Ind_addr2(IND_C);
  Ferrit[205] = Opcode(Op_ZQ);
  Ferrit[206] = Opcode(Op_HV) | Address1(208) | Ind_oper(IND_L) | Ind_addr1(IND_P) | Ind_addr2(IND_C);
  Ferrit[207] = Opcode(Op_ZQ);
  Ferrit[208] = Opcode(Op_HV) | Address1(210) | Ind_oper(IND_L) | Ind_addr1(IND_Q) | Ind_addr2(IND_C);
  Ferrit[209] = Opcode(Op_ZQ);
  Ferrit[210] = Opcode(Op_HV) | Address1(212) | Ind_oper(IND_L) | Ind_addr1(IND_R) | Ind_addr2(IND_C);
  Ferrit[211] = Opcode(Op_ZQ);
  Ferrit[212] = Opcode(Op_AR) | Smark  | Address1(211) | Ind_oper(IND_I) | Ind_addr1(IND_Z) | Ind_addr2(IND_B);
  Ferrit[213] = Opcode(Op_AR) | Address1(211) | Ind_oper(IND_I) | Ind_addr1(IND_Z) | Ind_addr2(IND_A);
  Ferrit[214] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_Z) | Ind_addr2(IND_B);
  Ferrit[215] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_Z) | Ind_addr2(IND_A);
  Ferrit[216] = Opcode(Op_PM) | Smark  | Ind_oper(IND_I) | Ind_addr1(IND_Z) | Ind_addr2(IND_C);
  Ferrit[217] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_Z) | Ind_addr2(IND_B);
  Ferrit[218] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_Z) | Ind_addr2(IND_A);
  Ferrit[219] = Opcode(Op_PI) | Smark;
  Ferrit[220] = Opcode(Op_QQ) | Ind_oper(IND_I) | Ind_addr1(IND_Z) | Ind_addr2(IND_B);
  Ferrit[221] = Opcode(Op_AR) | Address1(212);
  Ferrit[222] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_Z) | Ind_addr2(IND_B);
  Ferrit[223] = Opcode(Op_PI) | Smark;
  Ferrit[224] = Opcode(Op_QQ) | Ind_oper(IND_I) | Ind_addr1(IND_Z) | Ind_addr2(IND_A);
  Ferrit[225] = Opcode(Op_AR) | Address1(213);
  Ferrit[226] = Opcode(Op_ZQ) | Ind_oper(IND_N) | Ind_addr1(IND_Z) | Ind_addr2(IND_A);
  Ferrit[227] = Opcode(Op_PI);
  Ferrit[228] = Opcode(Op_HV) | Address1(198) | Ind_oper(IND_L) | Ind_addr1(IND_K) | Ind_addr2(IND_A);
  Ferrit[229] = Opcode(Op_HV) | Address1(41);
}

void demo23()
{
  /* Short indicator test */
  Ferrit[ 10] = Opcode(Op_PI) | Address1(15);
  Ferrit[ 11] = Opcode(Op_GI) | Address1(300) | Ind_oper(IND_M);
  Ferrit[ 12] = Opcode(Op_AR) | Smark | Address1(300);
  Ferrit[ 13] = Opcode(Op_PM) | Smark | Address1(400) | Ind_oper(IND_I) | Ind_addr1(IND_Q) | Ind_addr2(IND_A);
  Ferrit[ 14] = Opcode(Op_PM) | Smark | Address1(400) | Ind_oper(IND_I) | Ind_addr1(IND_Q) | Ind_addr2(IND_B);
  Ferrit[ 15] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_Q) | Ind_addr2(IND_A);
  Ferrit[ 16] = Opcode(Op_ZQ) | Ind_oper(IND_L) | Ind_addr1(IND_Q) | Ind_addr2(IND_B);
  Ferrit[ 17] = Opcode(Op_HV) | Address1(10);
}

void demo24()
{
  /* loudspeaker test, from ferrittest */
  Ferrit[10] = Opcode(Op_PS) | Smark | Address1(8);
  Ferrit[11] = Opcode(Op_PA) | r_relative | Address1(9) | Address2(9);
  Ferrit[12] = Opcode(Op_PA) | r_relative | Address1(5) | Address2(511); /* 511 */
  Ferrit[13] = Opcode(Op_PA) | r_relative | Address1(2) | Address2(7); /* 7 */
  Ferrit[14] = Opcode(Op_AR) | s_relative | Address1(128) | Dmark;
  Ferrit[15] = Opcode(Op_BT) | Address1(7) | Address2(-1);
  Ferrit[16] = Opcode(Op_HV) | r_relative | Address1(-2);
  Ferrit[17] = Opcode(Op_BT) | Address1(511) | Address2(-1);
  Ferrit[18] = Opcode(Op_HV) | r_relative | Address1(-5);
  Ferrit[19] = Opcode(Op_NS) | s_relative | Right(Opcode(Op_PS) | s_relative);
  Ferrit[20] = Opcode(Op_BT) | Address1(9) | Address2(-1);
  Ferrit[21] = Opcode(Op_HV) | r_relative | Address1(-9);
  Ferrit[22] = Opcode(Op_ZQ);
  Ferrit[23] = Opcode(Op_HV) | Address1(10);
}

void demo25()
{
  /* Simple loudspeaker test.
     Change M register manually to change frequency */
  Ferrit[10] = Opcode(Op_PM) | Smark | Address1(20);
  Ferrit[11] = Opcode(Op_GM) | Address1(21);
  Ferrit[12] = Opcode(Op_AR) | Address1(21);
  Ferrit[13] = Opcode(Op_HV) | r_relative | Address1(-2);
}

void demo26()
{
  /* Test of floating point zero switch. From ga4, pass 3 */
  Ferrit[10] = Opcode(Op_VY) | Address1(17);
  Ferrit[11] = Opcode(Op_AR) | Smark | Fmark | Address1(128)|Right(Opcode(Op_SR) | Address1(128));
  Ferrit[12] = Opcode(Op_GR) | Fmark | Address1(129);
  Ferrit[13] = Opcode(Op_NC) | Smark | Indirmark | Address1(129) | Right(Opcode(Op_HV) | Address1(18));
  Ferrit[14] = Opcode(Op_SY) | Address1(60) | Right(Opcode(Op_SY) | Address1(38));
  Ferrit[15] = Opcode(Op_SY) | Address1(34) | Right(Opcode(Op_SY) | Address1(58));
  Ferrit[16] = Opcode(Op_SY) | Address1(59) | Right(Opcode(Op_SY) | Address1(64));
  Ferrit[17] = Opcode(Op_ZQ) | Right(Opcode(Op_HV) | Address1(11));
  Ferrit[18] = Opcode(Op_SY) | Address1(58) | Right(Opcode(Op_SY) | Address1(53));
  Ferrit[19] = Opcode(Op_SY) | Address1(33) | Right(Opcode(Op_SY) | Address1(0));
  Ferrit[20] = Opcode(Op_HV) | Address1(14);
  Ferrit[128] = Opcode(Op_QQ) | Address1(1) | Address2(256);
  Ferrit[129] = Opcode(Op_QQ);
}

void demo27()
{
  /* Help 3 Track 0 loader */
  Ferrit[0] = Opcode(Op_TL) | Address1(-6) | Right(Opcode(Op_CA));
  Ferrit[1] = Opcode(Op_LY) | r_relative | Address1(4) | Right(Opcode(Op_HS));
  Ferrit[2] = Opcode(Op_GM) | s_relative | Address1(3) | Address2(-1) | Ind_oper(IND_M);
}

void demo28()
{
  /* Test of IS */
  Ferrit[430] = Opcode(Op_QQ) | p_relative | Address1(-472);
  Ferrit[431] = Opcode(Op_VK) | Address1(100);
  Ferrit[439] = Opcode(Op_IS) | Indirmark | r_relative | Address1(-9) | Right(Opcode(Op_SK) | s_relative | Address1(-39));
  Ferrit[440] = Opcode(Op_ZQ);
}

void demo29()
{
  /* Test of DK */
  Ferrit[0] = Opcode(Op_AR) | Smark | Address1(10);
  Ferrit[1] = Opcode(Op_DK) | Address1(11);
  Ferrit[2] = Opcode(Op_GR) | Address1(12);
  Ferrit[3] = Opcode(Op_AR) | Smark | Address1(13);
  Ferrit[4] = Opcode(Op_ZQ);
  Ferrit[10] = Opcode(Op_VY) | p_relative | Address1(-11) | Right(Opcode(Op_NK) | Smark | Indirmark | r_relative | Address1(19)); /* -0.02144660941 */
  Ferrit[11] = Opcode(Op_VY) | p_relative | Address1(373) | Address2(19) | Dmark | Ind_oper(IND_L) | Ind_addr1(IND_R) | Ind_addr2(IND_A); /* 0.7285533906 */
  Ferrit[12] = 0;
  Ferrit[13] = MASKINTAL(-0.02144660941/0.7285533906); /* Should be: -0.029437251 */
}

void demo30()
{
  int i;
  /* Test of IL/US:
     
     Transfer cells 240-880 to buffer 3000, and
     buffer 110-435 to cells 250 and on:
  */
  for(i=0; i<1024; i++) Ferrit[i] = ((GIERword)i)<<SHIFT39;
  for(i=0; i<4096; i++) Buffer[i] = ((GIERword)i)<<SHIFT39;
  Ferrit[0] = Opcode(Op_AR) | Smark | r_relative | Vmark |Address1(1);
  Ferrit[1] = (240ULL<<SHIFT9) | (641ULL<<SHIFT19) | (3000ULL<<SHIFT39);
  Ferrit[2] = Opcode(Op_US);
  Ferrit[3] = Opcode(Op_AR) | Smark | r_relative | Vmark |Address1(1);
  Ferrit[4] = (250ULL<<SHIFT9) | (326ULL<<SHIFT19) | (110ULL<<SHIFT39);
  Ferrit[5] = Opcode(Op_IL);
  Ferrit[6] = Opcode(Op_ZQ);
}

void demo31()
{
  /* Help 1 Track 0 loader */
  Ferrit[1] = Opcode(Op_LY) | Address1(0) | Right(Opcode(Op_TL) | Address1(-6));
  Ferrit[2] = Opcode(Op_CA) | Address1(0) | Right(Opcode(Op_HV) | Address1(1));
  Ferrit[3] = Opcode(Op_GM) | Address1(5) | Address2(-1) | Ind_oper(IND_M);
}

void demo32()
{
  /* Read test 21 using special loader */
  Ferrit[41] = Opcode(Op_LY) | Address1(43);
  Ferrit[42] = Opcode(Op_CL) | Address1(76);
  Ferrit[43] = Opcode(Op_GM) | Address1(0);
}

void demo33()
{
  /* Read combind tests */
  Ferrit[0] = Opcode(Op_LY) | Smark | Address1(-1) | Right(Opcode(Op_TK) | Address1(-16));
  Ferrit[1] = Opcode(Op_GR) | Address1(1) | Address2(1) | Ind_oper(IND_M);
}

void GIER_init(int ndrums, int usebuffer, int *newBDisk_tracksize, int *newBDisk_present, int *newBDisk_size)
{
  /*
  	ndrums is number of drums. This can be
	1, 2, 3 or 30 (meaning drum disk).

	newBDisk* are NULL, meaning no buffer disks,
	or arrays of size MAXBDISKS.
  */
  int i,j;
  Mode=Mode1;
  MA=1;
  LI=0ULL;
  OR=0ULL;
  MD=0ULL;
  H=0ULL;
  MQ=0ULL;
  AC=0ULL;
  AD0=0;
  AD1=0;
  TA=0;
  IN=0;
  OT=0; /* start in cell 0 */
  AD2=0;
  SR=0;
  TK=0;
  TG=960;
  BL=0;
  BY=0;
  BS=0;
  TD=0;
  TBA=0;
  h=0;
  b=0;
  c=0;
  spild=0;
  ind_ka=0;
  ind_kb=0;
  switch_k0=1; /* floating point zero switch */
  aarhus_mode=0; /* mode5 stores 0-39 on channel aarhus_mode?1:38 */
  track0_open=1;
  track1_31_open=1;
  testmode=0;
  reader_parity_error=0;
  GIER_stop();
  /* Zero core memory */

  for(i=0; i<1024; i++) Ferrit[i] = 0ULL;

  /* Create drum: */

  Tromle_size=320*ndrums;
  Tromle=(GIERword *) malloc(sizeof(*Tromle)*40*Tromle_size);
  for(i=0; i<Tromle_size; i++)
  for(j=0; j<40; j++) Tromle[i*40+j] = 0ULL;

  /* Create buffer storage */

  if(Buffer != NULL)
  {
    free((char *) Buffer);
    Buffer = NULL;
  }

  for(i=0; i<MAXBDISKS; i++)
  {
    if(BDisk[i]) free((char *) BDisk[i]);
    BDisk[i] = NULL;
    BDisk_present[i] = 0;
  }

  if(usebuffer)
  {
    Buffer = (GIERword *) malloc(sizeof(*Buffer)*4096);
    for(i=0; i<4096; i++) Buffer[i] = 0;
    if(newBDisk_present != NULL)
    {
      for(i=0; i<MAXBDISKS; i++)
      {
	BDisk_tracksize[i] = newBDisk_tracksize[i];
	BDisk_present[i] = newBDisk_present[i];
	BDisk_size[i] = newBDisk_size[i];
	if(BDisk_present[i])
	{
	  BDisk[i] = (GIERword *) malloc(sizeof(**BDisk)*BDisk_tracksize[i]*BDisk_size[i]);
	}
      }
    }
  }
  else
  {
    fprintf(stderr, "Use buffer: No\n");
  }

  for(i=0;i<MAXBTAPES;i++)
  {
    BTape[i] = NULL;
    BTape_len[i] = 0;
    BTape_current[i] = 0;
    BTape_status[i] = TAPE_LOADPOINT|TAPE_WRITABLE|TAPE_HD;
  }

  for(i=0;i<CARROUSELREELS;i++)
    for(j=0;j<CARROUSELBLOCKS;j++)
      BCarr[i][j] = NULL;

  selected_out[1] = 8;
  selected_out[2] = 16;
  selected_out[3] = 32;
  selected_out[4] = 64;

  debug=0;
  for(i=0; i<128; i++) statistics[i] = 0;

  /* demo31(); */
  demo27();
  /* demo33(); */
}

void print_statistics()
{
  int i;
  FILE *fh;

  if(debug&DEBUGstat)
  {
    fh = fopen("gierstat.dat", "w");
    if(fh != NULL)
    {
      for(i=0; i<128; i++)
      {
        fprintf(fh, "%s%s\t%ld\n", opcodes[i&63], i>63?"F":"", statistics[i]);
	statistics[i]=0;
      }
      fclose(fh);
    }
  }
  else
  {
    for(i=0; i<128; i++) statistics[i] = 0;
  }
}

void print_timing_statistics()
{
  int i;
  FILE *fh;

  if(debug&DEBUGtime)
  {
    fh = fopen("giertime.dat", "w");
    if(fh != NULL)
    {
      for(i=0; i<1024; i++)
      {
        fprintf(fh, "%d\t%lld\n", i, timing_statistics[i]);
	timing_statistics[i]=0;
      }
      fclose(fh);
    }
  }
  else
  {
    for(i=0; i<1024; i++) timing_statistics[i] = 0;
  }
}

static char *dumphalfword(GIERword w, int right)
{
  int fmark;
  int op,addr;
  static char result[40];

  fmark = w&ONE41;
  if(right) w = w<<10;

  op=(w&ONE20_25)>>SHIFT25;
  addr=(w&ONE0_9)>>SHIFT9;

  sprintf(result, "%s%s%s %s%s%s%s%d%s",
      opcodes[op],
      (w&ONE26)?"n":"",
      fmark?"f":"",
      (w&ONE27)?"(":"",
      ((w&ONE28_29)==ONE28)?"r":"",
      ((w&ONE28_29)==ONE29)?"s":"",
      ((w&ONE28_29)==ONE28_29)?"p":"",
      ((w&ONE28_29)==0)?addr:(((addr<512)?addr:addr-1024)),
      (w&ONE27)?")":"");
  return result;
}

void dumpword(FILE *fd, GIERword f)
{
  int i;
  int td;


  if(f & ONE40)
  {
    fprintf(fd, "%s, ", dumphalfword(f, 0));
    fprintf(fd, "%s", dumphalfword(f, 1));
  }
  else
  {
    td = (f&ONE10_19)>>SHIFT19;
    fprintf(fd, "%s ", dumphalfword(f, 0));
    if(td)
    {
      if(td>511)
	fprintf(fd, "t%d ", td-1024);
      else
	fprintf(fd, "t+%d ", td);
    }
    if(f&ONE30) fprintf(fd, "X");
    if(f&ONE31) fprintf(fd, "V");
    if(f&ONE32) fprintf(fd, "D");
    if(f&ONE33_39)
    {
      fprintf(fd, " ");
      switch((f&ONE33_34)>>SHIFT34)
      {
      case 0:
	fprintf(fd, "I");
	break;
      case 1:
	fprintf(fd, "M");
	break;
      case 2:
	fprintf(fd, "N");
	break;
      case 3:
	fprintf(fd, "L");
	break;
      }
      switch((f&ONE35_37)>>SHIFT37)
      {
      case 0:
	break;
      case 1:
	fprintf(fd, "K");
	break;
      case 2:
	fprintf(fd, "Z");
	break;
      case 3:
	fprintf(fd, "O");
	break;
      case 4:
	fprintf(fd, "T");
	break;
      case 5:
	fprintf(fd, "P");
	break;
      case 6:
	fprintf(fd, "Q");
	break;
      case 7:
	fprintf(fd, "R");
	break;
      }
      switch((f&ONE38_39)>>SHIFT39)
      {
      case 0:
	break;
      case 1:
	fprintf(fd, "B");
	break;
      case 2:
	fprintf(fd, "A");
	break;
      case 3:
	fprintf(fd, "C");
	break;
      }
    } /* Indicator */
  } /* Fullword */
}

void dumpgier()
{
  FILE *fd;
  int i;
  GIERword f;

  fd = fopen("gier.dump", "w");

  fprintf(fd, "r1: %d\n\nFerrit:\n\n", AD1);

  for(i=0; i<1024; i++)
  {
    f=Ferrit[i];
    fprintf(fd, "[%4.4d] ", i);
    dumpword(fd,f);
    fprintf(fd, "\n");
  } /* Each word */

  fprintf(fd, "\nDrum:\n\n");
  for(i=0; i<320*40; i++)
  {
    f=Tromle[i];
    fprintf(fd, "[%6.6d] ", i);
    dumpword(fd,f);
    fprintf(fd, "\n");
  } /* Each word */
  fclose(fd);
}

static void ttest()
{
  int fd;
  unsigned char buffer[7];
  unsigned char c;
  GIERword w;
  int i,offset,uppercase;

  for(offset=0; offset<6; offset++)
  {
    fd=open("tapes/raw/bach/tape.flx", O_RDONLY);
    if(fd == -1) exit(-1);

    if(offset>0) read(fd, buffer, offset);

    fprintf(debug_fh, "\n    OFFSET: %d\n\n", offset);

    while(read(fd, buffer, 6)==6)
    {
      w = 0ULL;
      for(i=5; i>=0; i--)
      {
	w = (w<<7) | ((GIERword)remove_parity(buffer[i]));
      }
      dumpword(stdout, w);
      fprintf(debug_fh, "\n");
    }
    close(fd);
  }
}

void GIERmain()
{
  /* ttest(); exit(0); */

  interface_update_all();

  if(running) GIER_start();

  interface_run();
}

