
/*
	GIER microcode

	(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 <stdlib.h>
#include <time.h>
#include "GIER.h"
#include "common.h"

/* Because of the short-term memory in H and M,
   we'll need to store the contents of these
   registers before each microstep. */

static GIERword Hold,MQold;

static short whatever; /* Used in mode 5 */

static int adder_mode; /* 0: add, 1: subtract */
static int bufferaddr,bufferdevice,bufferdisk,bufferaddr,buffertrack,bufferlen,last_bufferlen,last_carrstatus,bufferstatus;
static void (*lastMode)();
static int lastMA;
extern char *opcodes[];

/*
	Interface stuff:
*/

static unsigned int step_count, sound_count_0, sound_count_1, SY_count;
unsigned long long clock_count, last_clock_count, base_clock_count, last_clock_count_HK, last_start_clock_count, last_execute_clock_count=0;
time_t start_time;
struct timespec start_clock;
static int last_instruction;

extern void typewriter_wait(int);
extern void reader_wait(int);
extern void GIER_stop();
extern void dumpword(FILE *,GIERword);
extern void GIERdemocommand();
extern void printer_SY(char);
extern void typewriter_SY(char);
extern void punch_SY(char);
extern void plotter_SY(char);
extern void plotter_set_pen(int,int);
extern void sound_update(int);
extern void kb12_update();
extern void sound_sync();
extern unsigned char remove_parity(unsigned char);
extern int check_parity(unsigned char);
extern GIERword FLYDENDE(double);
extern void nimbi_board_poll();

extern unsigned char flx2a(unsigned char, int *);
extern 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)
*/
extern int demomode;
extern char demoline[100];
extern int demosleep;
extern int demochar;

/*
	Forward declarations:
*/
void ModeLK();
void ModeSK();
void Mode1();
void Mode2();
void Mode3();
void Mode4();
void Mode5();
static void indicator_operation();
static int indicator_fulfilled();
static int jLY();
static int is_filemark(int tapeno);
static void append_block(int tapeno, int len, int wordlen, int parity, int buffer_addr);
int is_drum_running();
int drumstat=1;
void wait_drum();
static void start_drum_disk();

static double deltaclock()
{
  time_t time1;
  long time1ns;
  struct timespec clock1;
  double dtime1;
  clock_gettime(CLOCK_REALTIME, &clock1);
  time1 = clock1.tv_sec - start_clock.tv_sec;
  time1ns = clock1.tv_nsec - start_clock.tv_nsec;
  if(time1ns < 0)
  {
    time1--;
    time1ns += 1000000000;
  }
  dtime1 = (double) time1;
  dtime1 += ((double) time1ns)/1.0e9;
  return dtime1;
}

/*
	BUS functions:
*/

/* This is done before each microstep.
   The bus is set to all ones, and the contents of
   H and M are stored in temporary locations. */
#define BUSinit BUS = ONE00_41; Hold = H; MQold = MQ

/*
	Gs operations.

	These transfer information from a register
	to the bus
*/
/* If a register without 00 is read to the bus, duplicate
   0 into 00
*/
#define Set00 BUS &= (~ONE00) | (BUS & ONE0)<<(SHIFT00-SHIFT0)


/* Transfer H to the bus */
#define Gs_H00_9 BUS &= (~ONE00_9) | (Hold & ONE00_9)
#define Gs_H00_39 BUS &= (~ONE00_39) | (Hold & ONE00_39)
#define Gs_H0_9 BUS &= (~ONE0_9) | (Hold & ONE0_9); Set00
#define Gs_H10_19 BUS &= (~ONE10_19) | (Hold & ONE10_19)
#define Gs_H10_29 BUS &= (~ONE10_29) | (Hold & ONE10_29)
#define Gs_H20_29 BUS &= (~ONE20_29) | (Hold & ONE20_29)
#define Gs_H30_39 BUS &= (~ONE30_39) | (Hold & ONE30_39)

/* Transfer MQ to the bus */
#define Gs_MQ0_9 BUS &= (~ONE0_9) | (MQold & ONE0_9); Set00
#define Gs_MQ0_19 BUS &= (~ONE0_19) | (MQold & ONE0_19); Set00
#define Gs_MQ0_39 BUS &= (~ONE0_39) | (MQold & ONE0_39); Set00
#define Gs_MQ10_19 BUS &= (~ONE10_19) | (MQold & ONE10_19)
#define Gs_MQ10_39 BUS &= (~ONE10_39) | (MQold & ONE10_39)
#define Gs_MQ20_29 BUS &= (~ONE20_29) | (MQold & ONE20_29)
#define Gs_MQ30_39 BUS &= (~ONE30_39) | (MQold & ONE30_39)

/* Transfer SR to the bus */
#define Gs_SR BUS &= (~ONE0_9) | (((GIERword)SR)<<SHIFT9); Set00

/* Transfer OT to the bus */
#define Gs_OT BUS &= (~ONE0_9) | (((GIERword)OT)<<SHIFT9); Set00

/* Transfer TK to the bus */
#define Gs_TA BUS &= (~ONE0_9) | (((GIERword)TA)<<SHIFT9); Set00
#define Gs_TK BUS &= (~ONE0_9) | (((GIERword)TK)<<SHIFT9); Set00
#define Gs_TG BUS &= (~ONE0_9) | (((GIERword)TG)<<SHIFT9); Set00

/* Transfer TD (pos 10-19) to the bus, pos 0-9 */
#define Gs_TD_skraa BUS &= (~ONE0_9) | (((GIERword)TD)<<SHIFT9); Set00

/* Transfer AD2 (pos 0-9) to the bus, pos 10-19 */
#define Gs_AD2_skraa BUS &= (~ONE10_19) | (((GIERword)AD2)<<SHIFT19)

/* Transfer AD2 to the bus */
#define Gs_AD2 BUS &= (~ONE0_9) | (((GIERword)AD2)<<SHIFT9); Set00

/* Transfer TD to the bus pos 10-19 */
#define Gs_TD BUS &= (~ONE10_19) | (((GIERword)TD)<<SHIFT19)

/* Transfer lines 30-39 to lines 20-29 */
#define Gs_Linie30_39_Linie_20_29 BUS &= (~ONE20_29) | ((BUS&ONE30_39)<<(SHIFT20-SHIFT30))

/* Store the number 39 in TD
   This is used for counting in divide and multiply
*/
#define Gs_39_TD TD = 39

/* Aarhus GIER stores cell 0-39 on track 1 */
static int aarhus_modes[] = {39,2,320,640,960}; /* parameter track +1 */
#define Gs_39_TDmode5 TD = (aarhus_modes[aarhus_mode])

/* Transfer the contents of the indicator to the bus */
#define Gs_IN BUS &= (~ONE0_9) | (((GIERword)IN)<<SHIFT9); Set00

/* Bits 2-9 of BS to the bus */
#define Gs_BS2_9 BUS &= (~ONE2_9) | (((GIERword)BS)<<SHIFT9)

/* Bit 0,2-9 of BL to the bus */
#define Gs_BL02_9 BUS &= (~(ONE0|ONE2_9)) | ((((GIERword)BL)<<SHIFT9)&(ONE0|ONE2_9)); Set00

/* Set h to 1. Next operation is right halfword */
#define Gs_1h h = 1
/* Set h to 0. Next operation is left halfword */
#define Gs_0h h = 0

/* BY to the bus */
#define Gs_BY0_9 BUS &= (~ONE0_9) | (((GIERword)BY)<<SHIFT9); Set00

/* Not used */
#define Gs_TR_adder ;

/* MD to the bus */
#define Gs_MD00_39 BUS &= (~ONE00_39) | (MD & ONE00_39)
#define Gs_MD00_41 BUS &= MD
#define Gs_MD0_9 BUS &= (~ONE0_9) | (MD & ONE0_9); Set00
#define Gs_MD0_39 BUS &= (~ONE0_39) | (MD & ONE0_39); Set00
#define Gs_MD0_41 BUS &= (~ONE0_41) | (MD & ONE0_41); Set00
#define Gs_MD10_19 BUS &= (~ONE10_19) | (MD & ONE10_19)
#define Gs_MD10_39 BUS &= (~ONE10_39) | (MD & ONE10_39)
#define Gs_MD20_29 BUS &= (~ONE20_29) | (MD & ONE20_29)
#define Gs_MD30_39 BUS &= (~ONE30_39) | (MD & ONE30_39)

/* not used */
#define Gs_TBA ;
#define Gs_1CO ;
#define Gs_1AOK ;
#define Gs_1_Zs ;

/* flags */
#define Gs_1b b = 1
#define Gs_1c c = 1

/* dummy */
#define Gs_blind ;

/* transfer LI to the bus */
#define Gs_LI0_9 BUS &= (~ONE0_9) | (LI & ONE0_9); Set00
#define Gs_LI0_19 BUS &= (~ONE0_19) | (LI & ONE0_19); Set00
#define Gs_LI0_39 BUS &= (~ONE0_39) | (LI & ONE0_39); Set00
#define Gs_LI0_41 BUS &= (~ONE0_41) | (LI & ONE0_41); Set00
#define Gs_LI0_41_drum BUS &= (~ONE0_41) | (LI_drum & ONE0_41); Set00
#define Gs_LI10_19 BUS &= (~ONE10_19) | (LI & ONE10_19)
#define Gs_LI10_39 BUS &= (~ONE10_39) | (LI & ONE10_39)
#define Gs_LI20_29 BUS &= (~ONE20_29) | (LI & ONE20_29)
#define Gs_LI20_41 BUS &= (~ONE20_41) | (LI & ONE20_41)
#define Gs_LI30_39 BUS &= (~ONE30_39) | (LI & ONE30_39)
#define Gs_LI40_41 BUS &= (~ONE40_41) | (LI & ONE40_41)

/* transfer AC to the bus */
#define Gs_AC00_9 BUS &= (~ONE00_9) | (AC & ONE00_9)
#define Gs_AC00_39 BUS &= (~ONE00_39) | (AC & ONE00_39)
#define Gs_AC00_39H40_41 BUS = (AC & ONE00_39) | (Hold & ONE40_41)
#define Gs_AC10_19 BUS &= (~ONE10_19) | (AC & ONE10_19)
#define Gs_AC10_39H40_41 BUS &= (~ONE10_41) | (AC & ONE10_39) | (Hold & ONE40_41)
#define Gs_AC20_29 BUS &= (~ONE20_29) | (AC & ONE20_29)
#define Gs_AC20_41 BUS &= (~ONE20_41) | (AC & ONE20_41)
#define Gs_AC30_39H40_41 BUS &= (~ONE30_41) | (AC & ONE30_39) | (Hold & ONE40_41)

/* Change mode */
#define Gs_Mode1 Mode = Mode1
#define Gs_Mode2 Mode = Mode2
#define Gs_Mode3 Mode = Mode3
#define Gs_Mode4 Mode = Mode4

/* Dummy drum stuff */
#define Gs_TI0_9 /* Drum: Dummy */
#define Gs_TI10_19 /* Drum: Dummy */
#define Gs_TI20_29 /* Drum: Dummy */
#define Gs_TI30_41 /* Drum: Dummy */

#define Gs_stop_B_puls MA=drumsave_MA; Mode=drumsave_Mode; drum_cell_count++; if(drum_cell_count==41) {drum_running=0; disk_status=0;}
#define Gm_skift_B_A ;
/* Transfer AD0 to the bus */
#define Gs_AD0 BUS &= (~ONE0_9) | (((GIERword)AD0)<<SHIFT9); Set00
/* Note, AD0 is in fact OR0_9! */
#define Gs_OR0_9 Gs_AD0
#define Gs_OR20_29 BUS &= (~ONE20_29) | (OR & ONE20_29)
#define Gs_OR20_41 BUS &= (~ONE20_41) | (OR & ONE20_41)
#define Gs_OR30_41 BUS &= (~ONE30_41) | (OR & ONE30_41)

/* Transfer AD1 to the bus */
#define Gs_AD1 BUS &= (~ONE0_9) | (((GIERword)AD1)<<SHIFT9); Set00

/* Sometimes Gs sometimes Gm? */
#define Gs_spild Gm_spild
#define Gs_tael_i_TD Gm_tael_i_TD

/* Transfer BT to the bus */
#define Gs_BT3_9 BUS &= (~ONE3_9) | (((GIERword)BT)<<SHIFT9)
#define Gs_BT0_9 BUS &= (~ONE0_9) | (((GIERword)BT)<<SHIFT9); Set00

/* Zero bus lines: */
#define Gs_o0_9 BUS &= ~(ONE00_9)
#define Gs_o0o2_9 BUS &= ~(ONE00|ONE0|ONE2_9)
#define Gs_o0o2_19 BUS &= ~(ONE00|ONE0|ONE2_19)
#define Gs_o0o2_41 BUS &= ~(ONE00|ONE0|ONE2_41)
#define Gs_o0_19 BUS &= ~(ONE00_19)
#define Gs_o0_41 BUS &= ~(ONE00_41)
#define Gs_o1 BUS &= ~ONE1
#define Gs_o4_9 BUS &= ~(ONE4_9)
#define Gs_o10_14o19 BUS &= ~(ONE10_14|ONE19)
#define Gs_o10_19 BUS &= ~(ONE10_19)
#define Gs_o10_41 BUS &= ~(ONE10_41)
#define Gs_o15_18 BUS &= ~(ONE15_18)
#define Gs_o20_29 BUS &= ~(ONE20_29)
#define Gs_o20_41 BUS &= ~(ONE20_41)
#define Gs_o30_39 BUS &= ~(ONE30_39)

/*
	Gm operations.

	These transfer information from the bus to
	a register
*/

/* bus to H */
#define Gm_H00_9 H = (H & ~ONE00_9) | (BUS & ONE00_9)
#define Gm_H00_39 H = (H & ~ONE00_39) | (BUS & ONE00_39)
#define Gm_H00_41 H = BUS
#define Gm_H10_19 H = (H & ~ONE10_19) | (BUS & ONE10_19)
#define Gm_H10_39 H = (H & ~ONE10_39) | (BUS & ONE10_39)
#define Gm_H20_29 H = (H & ~ONE20_29) | (BUS & ONE20_29)
#define Gm_H20_39 H = (H & ~ONE20_39) | (BUS & ONE20_39)
#define Gm_H30_39 H = (H & ~ONE30_39) | (BUS & ONE30_39)
#define Gm_H40_41 H = (H & ~ONE40_41) | (BUS & ONE40_41)
/* zero H00 */
#define Gm_oH00 H = H & ~ONE00
/* Bus 0 to H00 */
#define Gm_Linie0_H00 H = (H & ~ONE00) | ((BUS & ONE0)<<1)

/* bus to H, right shift */
#define Gm_H1_9hs H = (H & ~ONE1_9) | ((BUS & ONE0_8)>>1)
#define Gm_H1_39hs H = (H & ~ONE1_39) | ((BUS & ONE0_38)>>1)
#define Gm_H10_19hs H = (H & ~ONE10_19) | ((BUS & ONE9_18)>>1)
#define Gm_H20_29hs H = (H & ~ONE20_29) | ((BUS & ONE19_28)>>1)
#define Gm_H30_39hs H = (H & ~ONE30_39) | ((BUS & ONE29_38)>>1)
/* Bus 00 to H00 and H0 */
#define Gm_Linie00_H00_H0 H = (H & ~ONE00_0) | (BUS & ONE00) | ((BUS & ONE00)>>1)
/* MQ39 to H0 */
#define Gm_MQ39_H0 H = (H & ~ONE0) | ((MQ & ONE39)<<(SHIFT0-SHIFT39))
/* Bus 39 to H0 */
#define Gm_Linie39_H0 H = (H & ~ONE0) | ((BUS & ONE39)<<(SHIFT0-SHIFT39))
/* bus to H, left shift */
#define Gm_H0_9vs H = (H & ~ONE0_9) | ((BUS & ONE1_10)<<1)
#define Gm_H0_19vs H = (H & ~ONE0_19) | ((BUS & ONE1_20)<<1)
#define Gm_H0_38vs H = (H & ~ONE0_38) | ((BUS & ONE1_39)<<1)
#define Gm_H10_19vs H = (H & ~ONE10_19) | ((BUS & ONE11_20)<<1)
#define Gm_H10_38vs H = (H & ~ONE10_38) | ((BUS & ONE11_39)<<1)
#define Gm_H20_29vs H = (H & ~ONE20_29) | ((BUS & ONE21_30)<<1)
#define Gm_H30_38vs H = (H & ~ONE30_38) | ((BUS & ONE31_39)<<1)
/* MQ0 to H39 */
#define Gm_MQ0_H39 H = (H & ~ONE39) | ((MQ & ONE0)>>(SHIFT0-SHIFT39))
#define Gm_MQ0_H39strange2 H=H
#define Gm_MQ0_H39strange if(debug&DEBUGmicrostep) fprintf(debug_fh, "Gm_MQ0_H39strange: %d\n", (MQ&ONE0)?1:0); H = (H & ~ONE39) | ((MQ & ONE0)>>(SHIFT0-SHIFT39))
/* Zero H39 */
#define Gm_oH39 H = H & ~ONE39
/* Bus 0 to H39 */
#define Gm_Linie0_H39 H = (H & ~ONE39) | ((BUS & ONE0)>>(SHIFT0-SHIFT39))
/* bus to LI */
#define Gm_LI0_9 LI = (LI & ~ONE0_9) | (BUS & ONE0_9)
#define Gm_LI0_19 LI = (LI & ~ONE0_19) | (BUS & ONE0_19)
#define Gm_LI0_39 LI = (LI & ~ONE0_39) | (BUS & ONE0_39)
#define Gm_LI0_41 LI = (BUS & ONE0_41)
#define Gm_LI0_41_drum LI_drum = (BUS & ONE0_41)
#define Gm_LI10_19 LI = (LI & ~ONE10_19) | (BUS & ONE10_19)
#define Gm_LI10_39 LI = (LI & ~ONE10_39) | (BUS & ONE10_39)
#define Gm_LI20_29 LI = (LI & ~ONE20_29) | (BUS & ONE20_29)
#define Gm_LI30_39 LI = (LI & ~ONE30_39) | (BUS & ONE30_39)
#define Gm_LI40_41 LI = (LI & ~ONE40_41) | (BUS & ONE40_41)

/* Indicator operation is special; done in a function */
#define Gm_IO indicator_operation()

/* Bus to SR */
#define Gm_SR SR = (BUS & ONE0_9)>>SHIFT9

/* Bus to AC */
#define Gm_AC00_9 AC = (AC & ~ONE00_9) | (BUS & ONE00_9)
#define Gm_AC00_39 AC = (AC & ~ONE00_39) | (BUS & ONE00_39)
#define Gm_AC00_41 AC = BUS
#define Gm_AC00_39H40_41 AC = (AC & ~ONE00_39) | (BUS & ONE00_39); H = (H & ~ONE40_41) | (BUS & ONE40_41)
#define Gm_AC10_19 AC = (AC & ~ONE10_19) | (BUS & ONE10_19)
#define Gm_AC10_39 AC = (AC & ~ONE10_39) | (BUS & ONE10_39)
#define Gm_AC20_29 AC = (AC & ~ONE20_29) | (BUS & ONE20_29)
#define Gm_AC30_39 AC = (AC & ~ONE30_39) | (BUS & ONE30_39)

/* Bus to OT */
#define Gm_OT OT = (BUS & ONE0_9)>>SHIFT9

/* Bus to MQ */
#define Gm_MQ0_9 MQ = (MQ & ~ONE0_9) | (BUS & ONE0_9)
#define Gm_MQ0_19 MQ = (MQ & ~ONE0_19) | (BUS & ONE0_19)
#define Gm_MQ0_39 MQ = (MQ & ~ONE0_39) | (BUS & ONE0_39)
#define Gm_MQ10_19 MQ = (MQ & ~ONE10_19) | (BUS & ONE10_19)
#define Gm_MQ10_39 MQ = (MQ & ~ONE10_39) | (BUS & ONE10_39)
#define Gm_MQ20_29 MQ = (MQ & ~ONE20_29) | (BUS & ONE20_29)
#define Gm_MQ20_39 MQ = (MQ & ~ONE20_39) | (BUS & ONE20_39)
#define Gm_MQ30_39 MQ = (MQ & ~ONE30_39) | (BUS & ONE30_39)

/* Right shift MQ; bus is not used */
#define Gm_MQ1_9hs MQ = (MQ & ~ONE1_9) | ((MQold & ONE0_8)>>1)
#define Gm_MQ1_19hs MQ = (MQ & ~ONE1_19) | ((MQold & ONE0_18)>>1)
#define Gm_MQ1_39hs MQ = (MQ & ~ONE1_39) | ((MQold & ONE0_38)>>1)
#define Gm_MQ10_19hs MQ = (MQ & ~ONE10_19) | ((MQold & ONE9_18)>>1)
#define Gm_MQ20_29hs MQ = (MQ & ~ONE20_29) | ((MQold & ONE19_28)>>1)
#define Gm_MQ30_39hs MQ = (MQ & ~ONE30_39) | ((MQold & ONE29_38)>>1)

/* Bus 39 to MQ0 */
#define Gm_Linie39_MQ0 MQ = (MQ & ~ONE0) | ((BUS & ONE39)<<(SHIFT0-SHIFT39))

/* MQ39 to MQ0 */
#define Gm_MQ39_MQ0 MQ = (MQ & ~ONE0) | ((MQold & ONE39)<<(SHIFT0-SHIFT39))

/* Left shift MQ; bus is not used */
#define Gm_MQ0_9vs MQ = (MQ & ~ONE0_9) | ((MQold & ONE1_10)<<1)
#define Gm_MQ0_19vs MQ = (MQ & ~ONE0_19) | ((MQold & ONE1_20)<<1)
#define Gm_MQ0_38vs MQ = (MQ & ~ONE0_38) | ((MQold & ONE1_39)<<1)
#define Gm_MQ10_19vs MQ = (MQ & ~ONE10_19) | ((MQold & ONE11_20)<<1)
#define Gm_MQ20_29vs MQ = (MQ & ~ONE20_29) | ((MQold & ONE21_30)<<1)
#define Gm_MQ30_38vs MQ = (MQ & ~ONE30_38) | ((MQold & ONE31_39)<<1)

/* Set MQ39 to 0 */
#define Gm_0_MQ39 MQ = (MQ & ~ONE39)
/* Set MQ39 to 1 */
#define Gm_1_MQ39 MQ = MQ | ONE39
/* bus to AD0 */
#define Gm_AD0 AD0 = (BUS & ONE0_9)>>SHIFT9
/* bus to TD */
#define Gm_TD TD = (BUS & ONE10_19)>>SHIFT19
/* bus to OR */
#define Gm_OR20_29 OR = (OR & ~ONE20_29) | (BUS & ONE20_29)
#define Gm_OR20_26_40_41 OR = (OR & ~(ONE20_26|ONE40_41)) | (BUS & (ONE20_26|ONE40_41))
#define Gm_OR20_39 OR = (OR & ~ONE20_39) | (BUS & ONE20_39)
#define Gm_OR20_41 OR = (OR & ~ONE20_41) | (BUS & ONE20_41)
#define Gm_OR27_29 OR = (OR & ~ONE27_29) | (BUS & ONE27_29)
#define Gm_OR30_39 OR = (OR & ~ONE30_39) | (BUS & ONE30_39)
#define Gm_OR40_41 OR = (OR & ~ONE40_41) | (BUS & ONE40_41)
/* bus to AD2 */
#define Gm_AD2 AD2 = (BUS & ONE0_9)>>SHIFT9
/* Skip next clock cycle; ignored */
#define Gm_step step_count++; SY_count++; clock_count++; drum_count++; disk_count++; if(debug&DEBUGmicrostep) {fprintf(debug_fh, "Gm_step: MA=%02d\n", lastMA);}
/* Stop machine */
#define Gm_stop {GIER_stop(); if(demomode==5) { demomode=1; GIERdemocommand(); }}
#define Gm_1_Zl ;
/* bus to MD */
#define Gm_MD00_9 MD = (MD & ~ONE00_9) | (BUS & ONE00_9)
#define Gm_MD00_19 MD = (MD & ~ONE00_19) | (BUS & ONE00_19)
#define Gm_MD00_39 MD = (MD & ~ONE00_39) | (BUS & ONE00_39)
#define Gm_MD00_41 MD = BUS
#define Gm_MD0_19 MD = (MD & ~ONE0_19) | (BUS & ONE0_19)
#define Gm_MD0_39 MD = (MD & ~ONE0_39) | (BUS & ONE0_39)
#define Gm_MD0_41 MD = (MD & ~ONE0_41) | (BUS & ONE0_41)
#define Gm_MD10_19 MD = (MD & ~ONE10_19) | (BUS & ONE10_19)
#define Gm_MD10_39 MD = (MD & ~ONE10_39) | (BUS & ONE10_39)
#define Gm_MD20_29 MD = (MD & ~ONE20_29) | (BUS & ONE20_29)
#define Gm_MD20_39 MD = (MD & ~ONE20_39) | (BUS & ONE20_39)
#define Gm_MD20_41 MD = (MD & ~ONE20_41) | (BUS & ONE20_41)
#define Gm_MD30_39 MD = (MD & ~ONE30_39) | (BUS & ONE30_39)
/* Zero bit 0 of MQ */
#define Gm_0_MQ0 MQ &= ~ONE0
#define Gmj ;
/* Count down TD */
#define Gm_tael_i_TD TD = (TD-1)&ONEBYTE0_9
/* Count up OT */
#define Gm_tael_i_OT OT = (OT+1)&ONEBYTE0_9
/* bus line 0 to MQ39 */
#define Gm_Linie0_MQ39 MQ = (MQ & ~ONE39) | ((BUS & ONE0)>>(SHIFT0-SHIFT39))
/* bus to AD1 */
#define Gm_AD1 AD1 = (BUS & ONE0_9)>>SHIFT9
/* bus to TK */
#define Gm_TK TK = (BUS & ONE0_9)>>SHIFT9
#define Gm_TG TG = (BUS & ONE0_9)>>SHIFT9
/* bus to BL */
#define Gm_BL2_9 BL = (BUS & ONE2_9)>>SHIFT9
/* bus to BS */
#define Gm_BS3_9 BS = (BUS & ONE3_9)>>SHIFT9
#define Gm_1_ZL ZL = 1
/* bus to BY */
#define Gm_BY0_9 BY = (BUS & ONE0_9)>>SHIFT9
#define Gm_BY2_9 BY = (BUS & ONE2_9)>>SHIFT9
/* Register overflow: If H0 != H00, an overflow has occurred */
#define Gm_spild spild = ( (Hold & ONE00) !=0 ) != ( (Hold & ONE0) != 0)
/* bus to indicator */
#define Gm_IN IN = (BUS & ONE0_9)>>SHIFT9
/* Manipulate flags */
#define Gm_saetTL_0bc b=0; c=0
#define Gm_1b b=1
/* bus to TBA */
#define Gm_TBA TBA = (BUS & ONE0_9)>>SHIFT9
#define Gm_start_tromle_SK drum_mode=1; start_drum_disk();
#define Gm_start_tromle_LK drum_mode=0; start_drum_disk();
#define Gm_TA_til_AD1 ;
#define Gm_AD1_til_TA ;
#define Gs_TR_Add BUS &= (~ONE0_9) | (((GIERword)((TBA+drum_address)&1023))<<SHIFT9); Set00
#define Gm_TA TA = (BUS & ONE0_9)>>SHIFT9
#define Gs_AD1 BUS &= (~ONE0_9) | (((GIERword)AD1)<<SHIFT9); Set00

/*
	Ferrite core operations.

	Note, after a read operation, the whole contents of LI is
	written back into core. This is important to
	remember if a read operation doesn't read
	all the 42 bits.

	The drum variants are kludge...
*/

#define FL_race_test if(debug&DEBUGdrumrace) \
        { \
	  fprintf(debug_fh,"Drum race 1\n"); \
	  if(is_drum_running()) \
	  { \
	    fprintf(debug_fh,"Drum race 2 %d %d\n",AD1,TBA); \
	    if(TBA<=984) \
	    { \
              if(AD1 >= TBA && AD1 <= (TBA+39)) \
	      { \
		fprintf(debug_fh, "Drum race: AD1: %d TBA: %d\n",AD1,TBA); \
	      } \
	    } \
	    else \
	    { \
	      if(AD1 >= TBA || AD1 <= (TBA+39-1024)) \
	      { \
		fprintf(debug_fh, "Drum race: AD1: %d TBA: %d\n",AD1,TBA); \
	      } \
	    } \
	  } \
	}
#ifdef WINDOWS
#define FL_skriv Ferrit[AD1] = LI&ONE0_41; \
        if(debug&DEBUGmemory) \
	{ \
	  fprintf(debug_fh, "Writing %d: %I64u = ",AD1,(LI>>2)); \
	  printword(LI); \
	} \
        FL_race_test;
#else
#define FL_skriv Ferrit[AD1] = LI&ONE0_41; \
        if(debug&DEBUGmemory) \
	{ \
	  fprintf(debug_fh, "Writing %d: %llu = ",AD1,(LI>>2)); \
	  printword(LI); \
	} \
        FL_race_test;
#endif
#ifdef WINDOWS
#define FL_skriv_drum Ferrit[TA] = LI_drum&ONE0_41; \
        if(debug&DEBUGmemory) \
	{ \
	  fprintf(debug_fh, "Writing %d: (drum) %I64u = ",TA,(LI_drum>>2)); \
	  printword(LI_drum); \
	} 
#else
#define FL_skriv_drum Ferrit[TA] = LI_drum&ONE0_41; \
        if(debug&DEBUGmemory) \
	{ \
	  fprintf(debug_fh, "Writing %d: (drum) %llu = ",TA,(LI_drum>>2)); \
	  printword(LI_drum); \
	} 
#endif
#define FL_laes0_9 LI = (LI & ~ONE0_9) | (Ferrit[AD1] & ONE0_9); FL_skriv
#define FL_laes0_920_39 LI = (LI & ~(ONE0_9|ONE20_39)) | (Ferrit[AD1] & (ONE0_9|ONE20_39)); FL_skriv
#define FL_laes0_920_41 LI = (LI & ~(ONE0_9|ONE20_41)) | (Ferrit[AD1] & (ONE0_9|ONE20_41)); FL_skriv
#define FL_laes0_39 LI = (LI & ~ONE0_39) | (Ferrit[AD1] & ONE0_39); FL_skriv
#ifdef WINDOWS
#define FL_laes0_41 LI = (LI & ~ONE0_41) | (Ferrit[AD1] & ONE0_41); \
        if(debug&DEBUGmemory) \
	{ \
	  fprintf(debug_fh, "Reading %d: %I64u = ",AD1,(LI>>2)); \
	  printword(LI); \
        } \
        FL_race_test;
#else
#define FL_laes0_41 LI = (LI & ~ONE0_41) | (Ferrit[AD1] & ONE0_41); \
        if(debug&DEBUGmemory) \
	{ \
	  fprintf(debug_fh, "Reading %d: %llu %llu = ",AD1,(LI>>2)); \
	  printword(LI); \
        } \
        FL_race_test;
#endif
#ifdef WINDOWS
#define FL_laes0_41_drum LI_drum = (LI_drum & ~ONE0_41) | (Ferrit[TA] & ONE0_41); \
        if(debug&DEBUGmemory) \
	{ \
	  fprintf(debug_fh, "Reading %d: (drum) %I64u = ",TA,(LI_drum>>2)); \
	  printword(LI_drum); \
        }
#else
#define FL_laes0_41_drum LI_drum = (LI_drum & ~ONE0_41) | (Ferrit[TA] & ONE0_41); \
        if(debug&DEBUGmemory) \
	{ \
	  fprintf(debug_fh, "Reading %d: (drum) %llu = ",TA,(LI_drum>>2)); \
	  printword(LI_drum); \
        }
#endif
#define FL_laes10_19 LI = (LI & ~ONE10_19) | (Ferrit[AD1] & ONE10_19); FL_skriv
#define FL_laes10_39 LI = (LI & ~ONE10_39) | (Ferrit[AD1] & ONE10_39); FL_skriv
#define FL_laes10_41 LI = (LI & ~ONE10_41) | (Ferrit[AD1] & ONE10_41); FL_skriv
#define FL_laes20_29 LI = (LI & ~ONE20_29) | (Ferrit[AD1] & ONE20_29); FL_skriv
#define FL_laes20_39 LI = (LI & ~ONE20_39) | (Ferrit[AD1] & ONE20_39); FL_skriv
#define FL_laes20_41 LI = (LI & ~ONE20_41) | (Ferrit[AD1] & ONE20_41); FL_skriv
#define FL_laes30_39 LI = (LI & ~ONE30_39) | (Ferrit[AD1] & ONE30_39); FL_skriv
#define FL_laes40_41 LI = (LI & ~ONE40_41) | (Ferrit[AD1] & ONE40_41); FL_skriv

/*
	Drum operations

*/
#define Gs_TI0_41 \
                  if((TK+(TG-960)*960)<Tromle_size) \
		  { \
                    BUS=Tromle[40*(TK+(TG-960)*960)+drum_address]; \
		    TR_error = 0; \
		  } \
		  else \
		  { \
		    TR_error = 1; \
		    drum_cell_count--; \
		    if(debug&DEBUGdrum)fprintf(debug_fh, "Read outside drum: %d\n", (TK+(TG-960)*960)); \
		  }
#define Gm_TI0_41 \
		  if((TK+(TG-960)*960)<Tromle_size) \
		  { \
		    if( ((TK+(TG-960)*960)==0) && !track0_open) \
		    { \
		      TR_error = 1; \
		      drum_cell_count--; \
		      if(debug&DEBUGdrum)fprintf(debug_fh, "Write on locked channel 0\n"); \
		    } \
		    else \
		    { \
		      if( ((TK+(TG-960)*960)>=1 && (TK+(TG-960)*960)<=31) && !track1_31_open) \
		      { \
			TR_error = 1; \
			drum_cell_count--; \
			if(debug&DEBUGdrum)fprintf(debug_fh, "Write on locked channel 1-31\n"); \
		      } \
		      else \
		      { \
		        Tromle[40*(TK+(TG-960)*960)+drum_address]=BUS; \
			TR_error = 0; \
		      } \
		    } \
		  } \
		  else \
		  { \
		    if(Tromle_size>320) \
		    { \
		      TR_error = 1; \
		      drum_cell_count--; \
		      if(debug&DEBUGdrum)fprintf(debug_fh, "Write outside drum: %d\n", (TK+(TG-960)*960)); \
		    } \
		    else \
		      TR_error = 0; \
		  } 

/*
	The adder.

	Adds MD and H or subtracts MD from H
*/

#define Gs_Subtraktion adder_mode = 1
#define Gs_Addition adder_mode = 0

#define Adder ((adder_mode==0?( (Hold&ONE00_39)+(MD&ONE00_39) ):( (Hold&ONE00_39)-(MD&ONE00_39) ) )&ONE00_39)

#define Gs_Adder00_19 BUS &= (~ONE00_19) | (Adder & ONE00_19)
#define Gs_Adder20_39 BUS &= (~ONE20_39) | (Adder & ONE20_39)
#define Gs_Adder00_39 BUS &= (~ONE00_39) | Adder

/* Conditions */

/* Conditions, Mode 1 */

#define IF_LI40 ( (LI&ONE40)!=0 )		/* halfword orders */
#define IF_h (h)				/* right halfword */
#define IF_i ( (OR&ONE27)!= 0)			/* indirect address */
#define IF_r ( (OR&ONE28)!= 0)			/* relative address */
#define IF_s ( (OR&ONE29)!= 0)			/* s-relative address */
#define IF_B (indicator_fulfilled())		/* indicator fulfilled */
#define IF_d ( (OR&ONE32)!= 0)			/* D mark */
#define IF_q ( (!IF_TDeq0)&&(!IF_OR27)&&( (!IF_OR20) || IF_OR22 || IF_OR23 ) ) /* Static or counting? */
#define IF_S ( (OR&ONE26)!= 0)			/* S marked */

/* Conditions, Mode 2 */
/* GIER can operate with two types of floating point
   zeros, depending upon a switch, switch_k0.
   One is all zeros, and the other is zero mantissa
   and nonzero exponent */
#define IF_ACstareq0 ( ((AC&ONE00_39) == 0)&&switch_k0 )
#define IF_AC10 ( (AC&ONE10) != 0 )
#define IF_c (c)
#define IF_MD0 ( (MD&ONE0) != 0 )
#define IF_MD10 ( (MD&ONE10) != 0 )
#define IF_MD39 ( (MD&ONE39) != 0 )
#define IF_MQ9 ( (MQ&ONE9) != 0 )
#define IF_MQ10 ( (MQ&ONE10) != 0 )
#define IF_MQ38 ( (MQ&ONE38) != 0 )
#define IF_MQ39 ( (MQ&ONE39) != 0 )
#define IF_OR20 ( (OR&ONE20) != 0 )
#define IF_OR21 ( (OR&ONE21) != 0 )
#define IF_OR22 ( (OR&ONE22) != 0 )
#define IF_OR23 ( (OR&ONE23) != 0 )
#define IF_OR24 ( (OR&ONE24) != 0 )
#define IF_OR25 ( (OR&ONE25) != 0 )
#define IF_OR27 ( (OR&ONE27) != 0 )
#define IF_OR33 ( (OR&ONE33) != 0 )
#define IF_OR34 ( (OR&ONE34) != 0 )
#define IF_OR40 ( (OR&ONE40) != 0 )
#define IF_OR41 ( (OR&ONE41) != 0 )
#define IF_plus ( ((IF_OR24)&(!IF_OR25)) || ((IF_OR23)&&((!IF_OR25)!=(IF_MD0))))
#define IF_M ( (!IF_OR33)&&(IF_OR34) )
#define IF_H00eqMD0 ( ((Hold&ONE00)!=0) == ((MD&ONE0)!=0) )
#define IF_H0eqH1 ( ((Hold&ONE0)!=0) == ((Hold&ONE1)!=0) )
/*
	Device speeds:

	8	Line printer; full speed
	16	Typewriter: 10 cps, wait 45500 clock cycles
		I've increased the speed to 30 cps...
	32	Punch: 150 cps, wait 3000 clock cycles
	64	Plotter: 300 cps, wait 1500 clock cycles

	Do NOT set typewriter speed too fast; GA2 and GA3 will fail!
*/
/* #define IF_jSY ( SY_count<(((BY & (8+16+32+64))&selected_out[2])?15000:(((BY & (8+16+32+64))&selected_out[3])?3000:0))) */
#define IF_jSY ( SY_count<(((BY & (8+16+32+64))&selected_out[2])?15000: \
                          (((BY & (8+16+32+64))&selected_out[3])?3000: \
                          (((BY & (8+16+32+64))&selected_out[4])?1500: \
			   0))))
#define IF_BY8 ( (BY&ONEBYTE8)!=0 )
#define IF_BY9 ( (BY&ONEBYTE9)!=0 )
#define IF_jLY ( jLY() )
#define IF_AD1ge960 ( (AD1>=960)&&(AD1<1023) )
#define IF_Coeq0 1
#define IF_YEeq0 (AD1==0)
#define IF_AD1pos1eq1 ((AD1&ONEBYTE1)!=0)
#define IF_optaget (0)

/* Conditions, Mode 3 */

#define IF_ACeq0 ( (AC&ONE00_39) == 0 )		/* is R00 included? */
#define IF_MQ9eqMQ10 ( ((MQ&ONE9)!=0) == ((MQ&ONE10)!=0) )
#define IF_b (b)
#define IF_MQ9eqMQ11 ( ((MQ&ONE9)!=0) == ((MQ&ONE11)!=0) )
#define IF_H00eqH0 ( ((Hold&ONE00)!=0) == ((Hold&ONE0)!=0) )
#define IF_H00 ( (Hold&ONE00)!=0 )

/* Conditions, Mode 4 */

#define IF_X ( (OR&ONE30)!=0 )
#define IF_V ( (OR&ONE31)!=0 )
#define IF_IK ( (OR&ONE33_37)==ONE37 )

/* Conditions, Mode 5 */

#define IF_TL (!is_drum_running())
#define IF_TDeq0 ( TD==0 )

/* Misc */

/* Bits in indicator, IN.

   Note, KA and KB are stored separately */

#define IND_OA 0x200U
#define IND_OB 0x100U
#define IND_OC 0x300U
#define SHIFT_O 8

#define IND_TA 0x080U
#define IND_TB 0x040U
#define IND_TC 0x0c0U
#define SHIFT_T 6

#define IND_PA 0x020U
#define IND_PB 0x010U
#define IND_PC 0x030U
#define SHIFT_P 4

#define IND_QA 0x008U
#define IND_QB 0x004U
#define IND_QC 0x00cU
#define SHIFT_Q 2

#define IND_RA 0x002U
#define IND_RB 0x001U
#define IND_RC 0x003U
#define SHIFT_R 0

/* Indicator conditions */
#define IF_AC00 ( (AC&ONE00)!=0 )
#define IF_ACspild ( (AC & ONE00) !=0 ) != ( (AC & ONE0) != 0)

/* It looks like that R40&41 is in fact H40 and 41 */
#define IF_AC40 ( (H&ONE40)!=0 )
#define IF_AC41 ( (H&ONE41)!=0 )

#define IF_OA ( (IN&IND_OA) != 0 )
#define IF_OB ( (IN&IND_OB) != 0 )

#define IF_TA ( (IN&IND_TA) != 0 )
#define IF_TB ( (IN&IND_TB) != 0 )

#define IF_PA ( (IN&IND_PA) != 0 )
#define IF_PB ( (IN&IND_PB) != 0 )

#define IF_QA ( (IN&IND_QA) != 0 )
#define IF_QB ( (IN&IND_QB) != 0 )

#define IF_RA ( (IN&IND_RA) != 0 )
#define IF_RB ( (IN&IND_RB) != 0 )


#define PANIK(x) {fprintf(stderr, "%s: Line %d\n", x, __LINE__); exit(-1);}

/* Test printing functions */

static double GIER2d(GIERword w)
{
  double x;
  int exponent;
  if( (w&ONE10)==0 )
  {
    x=((double)(w&ONE10_39))/((double)ONE11);
  }
  else
  {
    x=-(((double)((-w)&ONE10_39))/((double)ONE11));
  }
  if( (w&ONE0)==0 )
  {
    exponent = (int) ((w&ONE0_9)>>SHIFT9);
  }
  else
  {
    exponent = ((int) ((w&ONE0_9)>>SHIFT9))-1024;
  }
  for(;exponent>0;exponent--) x = x*2.0;
  for(;exponent<0;exponent++) x = x*0.5;
  return x;
}

#ifdef STRANGE
GIERword DKFa,DKFb,DKFc;
int use_strange=0;

static GIERword IMPROVE_DKF(GIERword dkfa,GIERword dkfb)
{
  GIERword AC=0ULL,MQ=0ULL,H=0ULL,MD=0ULL,LI=0ULL;
  int AD1=0,AD2=0,TD=0,lastTD=0,adderMode=0,b=0,kbon=0;

  GIERword AdderF()
  {
    if(adderMode)
    {
      return((H+MD)&ONE0_39);
    }
    else
    {
      return((H-MD)&ONE0_39);
    }
  }

  void mdump(char *t, GIERword w)
  {
    sprintf(t, " %4d %4d %4d %4d", (w&ONE0_9)>>SHIFT9, (w&ONE10_19)>>SHIFT19, (w&ONE20_29)>>SHIFT29, (w&ONE30_39)>>SHIFT39);
  }

  double GIER2d(GIERword w)
  {
    double x;
    int exponent;
    if( (w&ONE10)==0 )
    {
      x=((double)(w&ONE10_39))/((double)ONE11);
    }
    else
    {
      x=-(((double)((-w)&ONE10_39))/((double)ONE11));
    }
    if( (w&ONE0)==0 )
    {
      exponent = (int) ((w&ONE0_9)>>SHIFT9);
    }
    else
    {
      exponent = ((int) ((w&ONE0_9)>>SHIFT9))-1024;
    }
    for(;exponent>0;exponent--) x = x*2.0;
    for(;exponent<0;exponent++) x = x*0.5;
    return x;
  }

  void mprint(char *t, GIERword w)
  {
    char r[80];
    mdump(r, w);
    printf("%s: %s %.18g\n", t, r, GIER2d(w));
  }

  void gprint(GIERword w)
  {
    printf("_r_e_a_l _1_0 %4d _1_0 %4d _1_0 %4d _1_0 %4d", (w&ONE0_9)>>SHIFT9, (w&ONE10_19)>>SHIFT19, (w&ONE20_29)>>SHIFT29, (w&ONE30_39)>>SHIFT39);
  }

  void gprint2(GIERword a, GIERword b)
  {
    printf("test(");
    gprint(a);
    printf(",\n     ");
    gprint(b);
    printf(");\n");
  }

  void sprint(GIERword w)
  {
    printf("%d/%d/%d/%d", (w&ONE0_9)>>SHIFT9, (w&ONE10_19)>>SHIFT19, (w&ONE20_29)>>SHIFT29, (w&ONE30_39)>>SHIFT39);
  }
  void sprint2(GIERword a, GIERword b)
  {
    sprint(a);
    printf("\n");
    sprint(b);
    printf("\n");
  }

  void dump(int mode, int MA)
  {
    char tAC[21],tMQ[21],tH[21],tMD[21],tAdder[21];
    if(kbon)
    {
      mdump(tAC, AC);
      mdump(tMQ, MQ);
      mdump(tH, H);
      mdump(tMD, MD);
      mdump(tAdder, AdderF());
      if(lastTD != TD)
      {
	printf("Mo MA TD      AC                    MQ                    H                     MD                    Adder\n");
      }
      lastTD=TD;
      printf("%2d %02d %2d  %s  %s  %s  %s  %s\n",mode,MA,TD,tAC,tMQ,tH,tMD,tAdder);
    }
  }

  GIERword DKF(GIERword ma, GIERword mb)
  {
    // RF:=ma
    AC=ma;
    dump(0,0);
    MQ=ma&ONE0_9;
    if(ma&ONE10)
    {
      AC=AC|ONE0_9;
    }
    else
    {
      AC=AC&(~ONE0_9);
    }
  // Mode 1
    b=0;
  // DK MA=1
    adderMode=0;
    H=AC;
    LI=mb;
    dump(2,1);
  // DK MA=2
    TD=30;
    dump(2,2);
  // DK MA=3
    AC=0ULL;
    b=1;
    dump(2,3);
  // DK MA=4
    AD2 = (LI&ONE0_9)>>SHIFT9;
    AC = LI&ONE10_39;
    dump(2,4);
  // DK MA=5
    if((AC&ONE10)==0)
    {
      // a>=0
      MD=AC&ONE10_39;
    }
    else
    {
      MD=(AC&ONE10_39)|ONE0_9;
    }
    dump(2,5);
  // DK MA=6
    if(AC|=0ULL)
    {
      AD1=(MQ&ONE0_9)>>SHIFT9;
      MQ=MQ&ONE0_9;
      dump(2,6);
      goto MA24;
    }
    else
    {
      H=(H&ONE10_39)|ONE0;
      MQ=MQ&ONE0_9;
      dump(2,6);
      goto Mode3MA8;
    }
  // DK MA=8
  MA8:
    H=((AdderF()<<1)&ONE0_38)|
      ((MQ>>(SHIFT0-SHIFT39))&ONE39);
    MQ=((MQ<<1)&ONE0_38)|ONE39;
    adderMode=0;
    dump(2,8);
  // DK MA=9
  MA9:
    AC=H;
    dump(2,9);
  // DK MA=10
  MA10:
    if(TD!=0)
    {
      H=((AdderF()<<1)&ONE0_38)|
	((MQ>>(SHIFT0-SHIFT39))&ONE39);
      TD--;
    }
    else
    {
      H=AdderF();
      dump(2,10);
      goto MA12;
    }
    dump(2,10);
  // DK MA=11
    if(((H>>(SHIFT0-SHIFT39))&ONE39)==((MD>>(SHIFT0-SHIFT39))&ONE39))
    {
      AC=H;
      MQ=((MQ<<1)&ONE0_38)|ONE39;
      dump(2,11);
      goto MA10;
    }
    else
    {
      H=((AC<<1)&ONE0_38)|
	((MQ>>(SHIFT0-SHIFT39))&ONE39);
      MQ=(MQ<<1)&ONE0_38;
      dump(2,11);
      goto MA9;
    }
  // DK MA=12
  MA12:
    if((H&ONE0)==(MD&ONE0))
    {
      AC=H;
    }
    else
    {
      MD = MD&ONE20_39;
      H = H&ONE0_29;
      dump(2,12);
      goto MA14;
    }
    dump(2,12);
  // DK MA=13
    MD=MD&ONE20_39;
    H=H|ONE30_39;
    dump(2,13);
  // DK MA=14
  MA14:
    if(b&&((MQ&ONE9)==0ULL))
    {
      H=MQ;
    }
    else if(b&&((MQ&ONE9)!=0ULL))
    {
      H=MQ|ONE0_9;
    }
    else
    {
      printf("Ups\n");
    }
    dump(2,14);
  // DK MA=15
  MA15:
    if(((MQ&ONE9)!=0)!=((MQ&ONE10)!=0))
    {
      //
    }
    else
    {
      MD=MD|ONE10_19;
      dump(2,15);
      goto MA17;
    }
  // DK MA=16
    H=((H>>1)&ONE1_39)|(H&ONE0);
    MQ=((MQ>>1)&ONE1_39)|(MQ&ONE0);
    dump(2,16);
  // DK MA=17
  MA17:
    if(!b)
    {
      printf("Ups2\n");
    }
    else
    {
      AC=H;
    }
    dump(2,17);
  // DK MA=18
    MD=(MD&ONE10_39)|(((GIERword)AD2)<<SHIFT9);
    MQ=(MQ&ONE20_39)|((MQ<<1)&ONE0_19);
    dump(2,18);
  // DK MA=19
    H=(((GIERword)AD1)<<SHIFT9)|ONE20_39;
    b=0;
    dump(2,19);
    goto Mode3MA13;
  // DK MA=24
  MA24:
    if(((H&ONE0)!=0ULL)==((MD&ONE0)!=0ULL))
    {
      AC=H;
      MQ=(MQ<<1)&ONE0_38;
      dump(2,24);
      goto MA10;
    }
    else
    {
      MQ=(MQ&ONE1_39)|((H<<(SHIFT0-SHIFT39))&ONE0);
      H=((H>>1)&ONE1_39)|(H&ONE0);
      adderMode=1;
      dump(2,24);
      goto MA8;
    }
  // Mode3 MA=6
  Mode3MA6:
    MQ=(MQ&ONE0_9)|(((GIERword)TD)<<SHIFT9);
    b=1;
    dump(3,6);
  // Mode3 MA=7
    if(b)
    {
      H=(H&ONE10_39)|(AdderF()&ONE0_9);
    }
    dump(3,7);
  // Mode3 MA=8
  Mode3MA8:
    if(1)
    {
      MQ=(MQ&ONE10_39)|(H&ONE0_9);
      dump(3,8);
      goto Mode3MA12;
    }
  // Mode3 MA=12
  Mode3MA12:
    H=(H&ONE10_39)|(AC&ONE0_9);
    dump(3,12);
    goto Mode4MA2;
  // Mode3 MA=13
  Mode3MA13:
    b=1;
    dump(3,13);
  // Mode3 MA=15
    if((((MQ&ONE9)!=0)!=((MQ&ONE10)!=0))&&b)
    {
      dump(3,15);
      goto Mode3MA6;
    }
    else if(((MQ&ONE9)!=0ULL)==((MQ&ONE10)!=0ULL))
    {
      AC=0ULL;
      dump(3,15);
      goto Mode3MA6;
    }
  // Mode4 MA=2
  Mode4MA2:
    dump(4,2);
    return((MQ&ONE0_9)|(AC&ONE10_39));
  }

  GIERword MKF(GIERword ma, GIERword mb)
  {
    // RF:=ma
    AC=ma;
    dump(0,0);
    MQ=ma&ONE0_9;
    if(ma&ONE10)
    {
      AC=AC|ONE0_9;
    }
    else
    {
      AC=AC&(~ONE0_9);
    }
  // Mode 1
    b=0;
  // MK MA=1
    adderMode=1;
    AD2=(MQ&ONE0_9)>>SHIFT9;
    TD=30;
    LI=mb;
    dump(2,1);
  // MK MA=2
    MQ=AC;
    dump(2,2);
  // MK MA=3
    TD--;
    dump(2,3);
  // MK MA=4
    MD=LI;
    dump(2,4);
  // MK MA=5
    if((MD&ONE10)==0ULL)
    {
      H=((MD&ONE10_39)<<1)&ONE10_38;
    }
    else
    {
      H=(((MD&ONE10_39)<<1)&ONE10_38)|ONE0_9;
    }
    dump(2,5);
  // MK MA=6
    AD1=((MD&ONE0_9)>>SHIFT9);
    dump(2,6);
  // MK MA=7
    MD=H;
    dump(2,7);
  // MK MA=8
    H=0ULL;
    dump(2,8);
    goto MA24;
  // MK MA=9
  MA9:
    dump(2,9);
  // MK MA=10
  MA10:
    if((TD!=0)&&((MQ&ONE38)!=0ULL)&&b)
    {
      H=AdderF();
      H=(H&ONE0)|((H&ONE0_38)>>1);
      MQ=((MQ&ONE39)<<(SHIFT0-SHIFT39))|((MQ&ONE0_38)>>1);
      TD--;
      dump(2,10);
      goto MA9;
    }
    else if((TD!=0)&&((MQ&ONE38)==0ULL)&&b)
    {
      H=AdderF();
      H=(H&ONE0)|((H&ONE0_38)>>1);
      MQ=((MQ&ONE39)<<(SHIFT0-SHIFT39))|((MQ&ONE0_38)>>1);
      TD--;
      dump(2,10);
      goto MA11;
    }
    else if(TD==0)
    {
      H=AdderF();
      H=(H&ONE0)|((H&ONE0_38)>>1);
      MQ=((MQ&ONE39)<<(SHIFT0-SHIFT39))|((MQ&ONE0_38)>>1);
      adderMode=0;
      dump(2,10);
      goto MA13;
    }
  // MK MA=11
  MA11:
    if((TD!=0)&&((MQ&ONE38)!=0ULL)&&b)
    {
      H=(H&ONE0)|((H&ONE0_38)>>1);
      MQ=((MQ&ONE39)<<(SHIFT0-SHIFT39))|((MQ&ONE0_38)>>1);
      TD--;
      dump(2,11);
      goto MA9;
    }
    else if((TD!=0)&&((MQ&ONE38)==0ULL)&&b)
    {
      H=(H&ONE0)|((H&ONE0_38)>>1);
      MQ=((MQ&ONE39)<<(SHIFT0-SHIFT39))|((MQ&ONE0_38)>>1);
      TD--;
      dump(2,11);
      goto MA11;
    }
    else if(TD==0)
    {
      H=(H&ONE0)|((H&ONE0_38)>>1);
      MQ=((MQ&ONE39)<<(SHIFT0-SHIFT39))|((MQ&ONE0_38)>>1);
      adderMode=0;
      dump(2,11);
      goto MA13;
    }
  // MK MA=13
  MA13:
    if((MQ&ONE39)!=0ULL)
    {
      //
    }
    else
    {
      adderMode=1;
      dump(2,13);
      goto MA15;
    }
    dump(2,13);
  // MK MA=14
    if(1)
    {
      MQ = AdderF();
      adderMode=1;
      dump(2,14);
      goto MA20;
    }
  // MK MA=15
  MA15:
    if(1)
    {
      MQ = H;
      dump(2,15);
      goto MA20;
    }
  // MK MA=20
  MA20:
    MD=(((GIERword) AD1)<<SHIFT9)|ONE10_39;
    dump(2,20);
  // MK MA=21
    if(((MQ&ONE9)!=0ULL)==((MQ&ONE10)!=0ULL))
    {
      H = (((GIERword) AD2)<<SHIFT9)&ONE0_9;
    }
    else
    {
      H = (((GIERword) AD2)<<SHIFT9)|ONE10_39;
      MQ=(MQ&ONE0)|((MQ>>1)&ONE1_39);
    }
    dump(2,21);
  // MK MA=22
  MA22:
    if(((MQ&ONE9)!=0ULL)==((MQ&ONE10)!=0ULL))
    {
      AC=MQ;
      b=0;
      dump(2,22);
      goto Mode3MA6;
    }
    else
    {
      H = (H&ONE10_39)|(AdderF()&ONE0_9);
      MQ=(MQ&ONE0)|((MQ>>1)&ONE1_39);
    }
    dump(2,22);
  // MK MA=23
    MD=(MD&ONE10_39);
    dump(2,23);
    goto MA22;
  // MK MA=24
  MA24:
    if((MQ&ONE39)!=0ULL)
    {
      b=1;
      TD--;
      dump(2,24);
      goto MA10;
    }
    else
    {
      b=1;
      TD--;
      dump(2,24);
      goto MA11;
    }
  // Mode3 MA=6
  Mode3MA6:
    MQ=(MQ&ONE0_9)|(((GIERword)TD)<<SHIFT9);
    b=1;
    dump(3,6);
  // Mode3 MA=7
    if(b)
    {
      H=(H&ONE10_39)|(AdderF()&ONE0_9);
    }
    dump(3,7);
  // Mode3 MA=8
  Mode3MA8:
    if(1)
    {
      MQ=(MQ&ONE10_39)|(H&ONE0_9);
      dump(3,8);
      goto Mode3MA12;
    }
  // Mode3 MA=12
  Mode3MA12:
    H=(H&ONE10_39)|(AC&ONE0_9);
    dump(3,12);
    goto Mode4MA2;
  // Mode3 MA=13
  Mode3MA13:
    b=1;
    dump(3,13);
  // Mode3 MA=15
    if((((MQ&ONE9)!=0)!=((MQ&ONE10)!=0))&&b)
    {
      dump(3,15);
      goto Mode3MA6;
    }
    else if(((MQ&ONE9)!=0ULL)==((MQ&ONE10)!=0ULL))
    {
      AC=0ULL;
      dump(3,15);
      goto Mode3MA6;
    }
  // Mode4 MA=2
  Mode4MA2:
    dump(4,2);
    return((MQ&ONE0_9)|(AC&ONE10_39));
  }

  GIERword test(GIERword a, GIERword b)
  {
    GIERword c,d,c3,d3,bestc3;
    double A,B,C,C3,Ddelta,Er;
    int delta,ddelta;
    c=DKF(a,b);
    d=MKF(c,b);
    A=GIER2d(a);
    B=GIER2d(b);
    C=A/B;
#if 0
    if(d==a)
    {
      printf("SAME delta=0\n");
      return(c);
    }
    else
    {
      for(delta=-2;delta<=2;delta++)
      {
	c3=c+(delta<<SHIFT39);
	d3=MKF(c3,b);
	if(d3==a)
	{
	  printf("IMPROVED delta=%d\n",delta);
	  return(c3);
	}
      }
    }
    return(c);
#else
    Ddelta = 1e100;
    ddelta = 1234;
    for(delta=-5;delta<=5;delta++)
    {
      c3=c+(delta<<SHIFT39);
      C3=GIER2d(c3);
      Er=C3-C;
      if(Er<0) Er=-Er;
      if(Er<Ddelta)
      {
	Ddelta=Er;
	ddelta=delta;
	bestc3=c3;
      }
    }
    return(bestc3);
#endif
  }

  return(test(dkfa,dkfb));
}
#endif

static void printshortbin(unsigned short w,int bold)
{
  int i;
  char c;
  for(i=9; i>=0; i--)
  {
    c = ((w>>i))&1?'1':'0';
    fprintf(debug_fh, "%c", c);
    if(bold&&0)
    {
      fprintf(debug_fh, "\b_");
    }
  }
}

static void printwordbin(GIERword w,int bold)
{
  int i;
  char c;
  for(i=42; i>=0; i--)
  {
    c = ((w>>i))&1?'1':'0';

    fprintf(debug_fh, "%c", c);
    if(bold&&0)
    {
      fprintf(debug_fh, "\b_");
    }
    if( (i==42) || (i==32) || (i==22) || (i==12) || (i==2) ) fprintf(debug_fh, " ");
  }
}

static GIERword lastAC=0,lastMQ=0,lastMD=0,lastH=0,lastLI=0,lastF=0;
static unsigned short lastOT=0,lastSR=0,lastAD1=0,lastAD2=0,lastIN=0;
static long macount=0;

static void microdump(char *text)
{
  GIERword F;
  
  return;
  if(!(debug&DEBUGmicrostep)) return;

  if(macount%9==0 && macount>0) fprintf(debug_fh, "\f");
  macount++;

#ifdef WINDOWS
  fprintf(debug_fh, "%s MA=%d clock=%I64d\n", text, MA, clock_count);
#else
  fprintf(debug_fh, "%s MA=%d clock=%lld\n", text, MA, clock_count);
#endif

  fprintf(debug_fh, " R: ");
  printwordbin(AC,AC!=lastAC);
  lastAC=AC;
  fprintf(debug_fh, " r1: ");
  printshortbin(OT,OT!=lastOT);
  lastOT=OT;
  fprintf(debug_fh, "\n");

  fprintf(debug_fh, " M: ");
  printwordbin(MQ,MQ!=lastMQ);
  lastMQ=MQ;
  fprintf(debug_fh, " s1: ");
  printshortbin(SR,SR!=lastSR);
  lastSR=SR;
  fprintf(debug_fh, "\n");

  fprintf(debug_fh, " O: ");
  printwordbin(MD,MD!=lastMD);
  lastMD=MD;
  fprintf(debug_fh, " r2: ");
  printshortbin(AD1,AD1!=lastAD1);
  lastAD1=AD1;
  fprintf(debug_fh, "\n");

  fprintf(debug_fh, " H: ");
  printwordbin(H,H!=lastH);
  lastH=H;
  fprintf(debug_fh, " s2: ");
  printshortbin(AD2,AD2!=lastAD2);
  lastAD2=AD2;
  fprintf(debug_fh, "\n");

  fprintf(debug_fh, " L: ");
  printwordbin(LI,LI!=lastLI);
  lastLI=LI;
  fprintf(debug_fh, " in: ");
  printshortbin(IN,IN!=lastIN);
  lastIN=IN;
  fprintf(debug_fh, "\n");

  fprintf(debug_fh, " F: ");
  F = (OR&ONE10_41)|(((GIERword) AD0)<<SHIFT9);
  printwordbin(F,F!=lastF);
  lastF=F;
  fprintf(debug_fh, " h:  %d", h);
  fprintf(debug_fh, "\n");

}

void printword(GIERword w)
{
  int i;
  int exponent;
  double x;
  long long ww;
  int uppercase;
  unsigned char c;

  printwordbin(w,0);

  fprintf(debug_fh, "    ");

  /* dumpword(debug_fh, w); */
  {
    if( (w&ONE0)==0 )
    {
      x=((double)(w&ONE0_39))/((double)ONE39);
    }
    else
    {
      x=-(((double)((-w)&ONE0_39))/((double)ONE39));
    }
    ww=w>>2;
    if((ww & 0x0000008000000000LL)!=0) ww |= 0xFFFFFE0000000000LL;
#ifdef WINDOWS
    fprintf(debug_fh, " %I64d", ww);
#else
    fprintf(debug_fh, " %lld", ww);
#endif
  }

  fprintf(debug_fh, " %d/%d/%d/%d",
                    ((int) ((w&ONE0_9)>>SHIFT9)),
                    ((int) ((w&ONE10_19)>>SHIFT19)),
                    ((int) ((w&ONE20_29)>>SHIFT29)),
                    ((int) ((w&ONE30_39)>>SHIFT39)));


  if(debug&DEBUGmaskintal)
  {
    fprintf(debug_fh, " Maskintal: ");
    if( (w&ONE0)==0 )
    {
      x=((double)(w&ONE0_39))/((double)ONE0);
    }
    else
    {
      x=-(((double)((-w)&ONE0_39))/((double)ONE0));
    }

    fprintf(debug_fh, " %.10lg", x);
  }

  if(debug&DEBUGflydende)
  {
    fprintf(debug_fh, " Flydende: ");
    x=GIER2d(w);


    fprintf(debug_fh, "%.9lg",x);
  }

  if(debug&DEBUGtext)
  {
    fprintf(debug_fh, "    \"");
    uppercase=0;
    for(i=30; i>=0; i-=6)
    {
      c = (int) ((w>>(SHIFT39+i))&63);
      c = flx2a(c, &uppercase);
      if(c==255) c='.';
      fprintf(debug_fh, "%c", c);
    }
    fprintf(debug_fh, "\"  ");
  }
    
  fprintf(debug_fh, "\n");
}

static void coredump()
{
  int i;
  double x;
  if(!(debug&(~DEBUGstat))) return;
  fprintf(debug_fh, "==========core==========\n");
  for(i=0;i<1024;i++)
  {
    if(caddress[i] != -1)
    {
      fprintf(debug_fh, "c%d: ",caddress[i]);
      if(caddress[i]<10) fprintf(debug_fh, " ");
    }
    else
    {
      fprintf(debug_fh, "     ");
    }
    fprintf(debug_fh, "[%4d] ",i);
    fprintf(debug_fh, " %4d/%4d/%4d/%4d%c",
	    (Ferrit[i]&ONE0_9)>>SHIFT9,
	    (Ferrit[i]&ONE10_19)>>SHIFT19,
	    (Ferrit[i]&ONE20_29)>>SHIFT29,
	    (Ferrit[i]&ONE30_39)>>SHIFT39,
	    " bac"[Ferrit[i]&ONE40_41]);
    if( (Ferrit[i]&ONE0)==0 )
    {
      x=((double)(Ferrit[i]&ONE0_39))/((double)ONE39);
    }
    else
    {
      x=-(((double)((-Ferrit[i])&ONE0_39))/((double)ONE39));
    }
    fprintf(debug_fh, " %14lld  ", (long long) x);
    dumpword(debug_fh, Ferrit[i]);
    if(caddress[i] != -1)
    {
      if(cnames[caddress[i]].text != NULL)
	fprintf(debug_fh, "\t\t; %s", cnames[caddress[i]].text);
    }

    fprintf(debug_fh, "\n");
  }
  fprintf(debug_fh, "========================\n");
}

static int dumpcnt=0;
static void segmentdump()
{
  int i,j,k,l,l2,ga4,iend;
  /* CA table stops at c49 in GA4 and c62+1 in GA3 */
  /* GA4 has c30 */
  return;
  if(!(debug&(~DEBUGstat))) return;
  if(cnames[30].caddress != -1)
  {
    i=cnames[49].caddress;
    ga4=1;
    iend=cnames[5].caddress;
    iend=(Ferrit[iend]&ONE0_9)>>SHIFT9;
  }
  else
  {
    i=cnames[62].caddress;
    if(i!=-1) i++;
    ga4=0;
    iend=cnames[21].caddress+1;
    iend=(Ferrit[iend]&ONE0_9)>>SHIFT9;
  }
  if(i == -1) return;
  dumpcnt++;
  fprintf(debug_fh, "\n=== Segment table ===\n");
  fprintf(debug_fh, "Track\tAddr\tPrio\n");
  while( ((j=((Ferrit[i]&ONE0_9)>>SHIFT9))!=0) &&
         ((Ferrit[i]&ONE20_41)==
	  ((400ULL<<SHIFT29)|
	   (960ULL<<SHIFT39)|
	   ONE40)) &&
	 i>=iend)
  {
    k=((Ferrit[i]&ONE10_19)>>SHIFT19);
    l=((Ferrit[k]&ONE0_9)>>SHIFT9);
    l2=l;
    if(l2>511) l2=l2-1024;
    fprintf(debug_fh, "%d\t%d\t%d\t%d\n",j,k,l2,l);
    i--;
  }
  /* one more */
  j=((Ferrit[i]&ONE0_9)>>SHIFT9);
  k=((Ferrit[i]&ONE10_19)>>SHIFT19);
  l=((Ferrit[k]&ONE0_9)>>SHIFT9);
  l2=l;
  if(l2>511) l2=l2-1024;
  fprintf(debug_fh, "%d\t%d\t%d\t%d\n",j,k,l2,l);
  fprintf(debug_fh, "=====================\n");
  coredump();
}

static void after_MA()
{
  if(debug&DEBUGBUS)
  {
    fprintf(debug_fh, "  BUS: ");
    printword(BUS);
  }
  if(debug&DEBUGregisters)
  {
    fprintf(debug_fh, "   AC: ");
    printword((AC&~ONE40_41)|(H&ONE40_41));
    fprintf(debug_fh, "    H: ");
    printword(H);
    fprintf(debug_fh, " Hold: ");
    printword(Hold);
    fprintf(debug_fh, "   MD: ");
    printword(MD);
    fprintf(debug_fh, "Adder%s ",(adder_mode==0)?"+":"-");
    printword(Adder);
    fprintf(debug_fh, "   MQ: ");
    printword(MQ);
    fprintf(debug_fh, "    TD: %d b: %d c: %d\n", TD, b, c);
  }
}

/*	Tape drive functions */

static void checkbuffer(int addr)
{
  if(addr<0 || addr>4095) fprintf(stderr, "checkbuffer: %d\n", addr);
  if((Buffer[addr] & (~ONE0_41)) != 0) fprintf(stderr, "checkbuffer: %d %llx\n", addr, Buffer[addr]);
}

static void dump_tapes(char *txt)
{
  btapeblock *cur;
  int tapeno;
  int fileno,blockno,savepos;
  if(!(debug&DEBUGbuffer)) return;
  fprintf(debug_fh, "Dump of tapes %s\n", txt);
  for(tapeno=1;tapeno<=6;tapeno++)
  {
    if(BTape_len[tapeno-1]>0)
    {
      savepos = BTape_current[tapeno-1];
      BTape_current[tapeno-1] = 0;
      fprintf(debug_fh, "  === Tape station %d (Status:", tapeno);
      if(BTape_status[tapeno-1] & TAPE_PARITY) fprintf(debug_fh, "PARITY ");
      if(BTape_status[tapeno-1] & TAPE_FILEMARK) fprintf(debug_fh, "FILEMARK ");
      if(BTape_status[tapeno-1] & TAPE_LOADPOINT) fprintf(debug_fh, "LOADPOINT ");
      if(BTape_status[tapeno-1] & TAPE_EOT) fprintf(debug_fh, "EOT ");
      if(BTape_status[tapeno-1] & TAPE_WRITABLE) fprintf(debug_fh, "WRITABLE ");
      if(BTape_status[tapeno-1] & TAPE_HD) fprintf(debug_fh, "HD ");
      fprintf(debug_fh, ")===\n\n");
      fileno=0;
      blockno=0;
      while(BTape_current[tapeno-1]<BTape_len[tapeno-1])
      {
	cur = &BTape[tapeno-1][BTape_current[tapeno-1]];
	fprintf(debug_fh, "%sFile %d Block %d: Parity: %d %d Word%s\n",
	    (BTape_current[tapeno-1]==savepos)?"--> ":"    ",
	    fileno, blockno, cur->parity, cur->len, (cur->len==1)?"":"s");
	blockno++;
	if(is_filemark(tapeno))
	{
	  fileno++;
	  blockno=0;
	}
	BTape_current[tapeno-1]++;
      }
      BTape_current[tapeno-1] = savepos;
    }
  }
  fflush(debug_fh);
}

static void first_block(int tapeno)
{
  BTape_current[tapeno-1]=0;
}

static void release_blocks(int tapeno)
{
  int i;
  for(i=BTape_current[tapeno-1]; i<BTape_len[tapeno-1]; i++)
  {
    if(BTape[tapeno-1][i].block != NULL)
    {
      free(BTape[tapeno-1][i].block);
      BTape[tapeno-1][i].block = NULL;
      BTape[tapeno-1][i].len = 0;
      if(debug&DEBUGbuffer) fprintf(debug_fh, "Release_blocks: Tape: %d Block: %d\n", tapeno, i);
    }
  }
}

static int is_filemark(int tapeno)
{
  btapeblock *cur;
  int i;
  GIERword eof;

  /* if(debug&DEBUGbuffer) fprintf(debug_fh, "is_filemark(%d): ", tapeno); */

  if(BTape_current[tapeno-1] >= BTape_len[tapeno-1])
  {
    /* if(debug&DEBUGbuffer) fprintf(debug_fh, "No, past end of tape.\n"); */
    return 0;
  }

  cur = &BTape[tapeno-1][BTape_current[tapeno-1]];

  if(cur->block == NULL)
  {
    /* if(debug&DEBUGbuffer) fprintf(debug_fh, "No, block is NULL.\n"); */
    return 0;
  }
  if(cur->len == 0)
  {
    /* if(debug&DEBUGbuffer) fprintf(debug_fh, "No, len is 0.\n"); */
    return 0;
  }

  /* The next test is removed; edit writes filemark with odd parity */
  /* if(cur->parity == 1) return 0; */ /* Must have even parity */
  if(cur->wordlen == 4)
  {
    eof = 0x0f3cf3c0000ULL; /* 4 bytes with 001111 */
  }
  else
  {
    eof = 0x0f3cf3cf3cfULL; /* 7 bytes with 001111 */
  }
  for(i=0;i<cur->len;i++)
  {
    if(cur->block[i]!=eof)
    {
      /* if(debug&DEBUGbuffer) fprintf(debug_fh, "No, not right cell content.\n"); */
      return 0;
    }
  }
  /* if(debug&DEBUGbuffer) fprintf(debug_fh, "YES.\n"); */
  return 1;
}

static void forward_filemark(int tapeno)
{
  int finish=0;
  btapeblock *last;

  while(!finish)
  {
    if(BTape_current[tapeno-1]>=BTape_len[tapeno-1]) return;
    finish=is_filemark(tapeno);
    BTape_current[tapeno-1]++;
  }
  BTape_status[tapeno-1] |= TAPE_FILEMARK;
}

static void backward_filemark(int tapeno)
{
  if(BTape_current[tapeno-1]==0) return;
  do
  {
    BTape_current[tapeno-1]--;
    if(BTape_current[tapeno-1]==0) return;
  }
  while(!is_filemark(tapeno));
  BTape_status[tapeno-1] |= TAPE_FILEMARK;
}

static void backward_block(int tapeno)
{
  if(BTape_current[tapeno-1]==0)
  {
    BTape_status[tapeno-1] = TAPE_LOADPOINT | TAPE_WRITABLE | TAPE_HD;
  }
  else
  {
    BTape_current[tapeno-1]--;
    BTape_status[tapeno-1] = (is_filemark(tapeno)?TAPE_FILEMARK:0) | TAPE_WRITABLE | TAPE_HD;
  }
}

static void append_block(int tapeno, int len, int wordlen, int parity, int buffer_addr)
{
  btapeblock *new;
  int i;
  GIERword mask;

  if(BTape_current[tapeno-1] >= BTape_len[tapeno-1])
  {
    BTape_len[tapeno-1] = BTape_current[tapeno-1]+1;
    if(debug&DEBUGbuffer) fprintf(debug_fh, "Resize tape %d to: %lu\n", tapeno, sizeof(**BTape)*BTape_len[tapeno-1]);
    BTape[tapeno-1] = realloc(BTape[tapeno-1], sizeof(**BTape)*BTape_len[tapeno-1]);
    for(i=BTape_current[tapeno-1]; i<BTape_len[tapeno-1]; i++) BTape[tapeno-1][i].block = NULL;
  }

  new = &BTape[tapeno-1][BTape_current[tapeno-1]];

  release_blocks(tapeno);

  new->len=len;
  new->wordlen=wordlen;
  new->parity=parity;
  mask = (wordlen==7)?ONE0_41:ONE0_23;
  new->block = (GIERword *) malloc(sizeof(GIERword)*len);
  for(i=0; i<len; i++)
    new->block[i] = Buffer[(buffer_addr+i)%4096]&mask;
  if(debug&DEBUGbuffer)
  {
    fprintf(debug_fh, "Tape block:\n");
    for(i=0; i<len; i++)
    {
      fprintf(debug_fh, "%04d: ", i);
      printword(new->block[i]);
    }
  }
  BTape_status[tapeno-1] = (is_filemark(tapeno)?TAPE_FILEMARK:0) | TAPE_WRITABLE | TAPE_HD | (((GIERword) len)<<SHIFT19);
  BTape_current[tapeno-1]++;
  dump_tapes("After write");
}

static void read_block(int tapeno, int len, int parity, int buffer_addr)
{
  btapeblock *cur;
  GIERword mask;
  int i,actuallen;

  if(BTape_current[tapeno-1] >= BTape_len[tapeno-1])
  {
    BTape_status[tapeno-1] = TAPE_EOT | TAPE_WRITABLE | TAPE_HD;
  }
  else
  {
    cur = &BTape[tapeno-1][BTape_current[tapeno-1]];
    if(cur->block == NULL)
    {
      BTape_status[tapeno-1] = TAPE_EOT | TAPE_WRITABLE | TAPE_HD;
    }
    else
    {
      mask = (cur->wordlen==7)?ONE0_41:ONE0_23;
      actuallen = cur->len;
      if(actuallen > len) actuallen=len;
      for(i=0; i<actuallen; i++)
      {
	Buffer[(buffer_addr+i)%4096] = cur->block[i]&mask;
        if(debug&DEBUGbuffer) checkbuffer(buffer_addr+i);
      }
      BTape_status[tapeno-1] = (is_filemark(tapeno)?TAPE_FILEMARK:0) | TAPE_WRITABLE | TAPE_HD | (((GIERword) (cur->len))<<SHIFT19) | ((parity!=cur->parity)?TAPE_PARITY:0);
      if(debug&DEBUGbuffer)
      {
	fprintf(debug_fh, "Tape status after read: ");
	if(BTape_status[tapeno-1] & TAPE_PARITY) fprintf(debug_fh, "PARITY ");
	if(BTape_status[tapeno-1] & TAPE_FILEMARK) fprintf(debug_fh, "FILEMARK ");
	if(BTape_status[tapeno-1] & TAPE_LOADPOINT) fprintf(debug_fh, "LOADPOINT ");
	if(BTape_status[tapeno-1] & TAPE_EOT) fprintf(debug_fh, "EOT ");
	if(BTape_status[tapeno-1] & TAPE_WRITABLE) fprintf(debug_fh, "WRITABLE ");
	if(BTape_status[tapeno-1] & TAPE_HD) fprintf(debug_fh, "HD ");
	fprintf(debug_fh, "\n");
      }
    }
  }
  BTape_current[tapeno-1]++;
  dump_tapes("After read");
}

/*
	Help functions for the indicator.
*/


/*
	Indicator fulfilled:
*/

static int indicator_fulfilled()
{
  /*
	This function returns 1 iff the current
	instruction is to be executed.
  */
  int IND_oper, IND_addr1, IND_addr2, value1;

  if(OR&ONE33)
  {
    IND_oper = (OR&ONE33_34)>>SHIFT34;
    IND_addr1 = (OR&ONE35_37)>>SHIFT37;
    IND_addr2 = (OR&ONE38_39)>>SHIFT39;
    value1 = (IND_oper == IND_L);

    if(debug&DEBUGindicator)
    {
      fprintf(debug_fh, "indicator_fulfilled: oper: %d, addr1: %d, addr2: %d\n", IND_oper, IND_addr1, IND_addr2);
    }

    switch(IND_addr1)
    {
    case IND_none: /* LA,LB,LC NA,NB,NC*/
      switch(IND_addr2)
      {
        case IND_none:
	  return 1;
	case IND_A:
	  return ( IF_AC40 == value1);
	case IND_B:
	  return ( IF_AC41 == value1);
	case IND_C:
	  return ( (IF_AC40 == value1) && (IF_AC41 == value1) );
      }
    case IND_K: /* LKA,LKB,LKC NKA,NKB,NKC */
      switch(IND_addr2)
      {
        case IND_none:
	  return 1;
	case IND_A:
	  return ( ind_ka == value1);
	case IND_B:
	  return ( ind_kb == value1);
	case IND_C:
	  return ( (ind_ka == value1) && (ind_kb == value1) );
      }
    case IND_Z:
      switch(IND_addr2)
      {
	case IND_none:
	  return ( IF_ACeq0 == value1 );
	case IND_A:
	  return ( IF_OA == value1 );
	case IND_B:
	  return ( IF_OB == value1 );
	case IND_C:
	  return ( (IF_OA == value1) && (IF_OB == value1) );
      }
    case IND_O:
      switch(IND_addr2)
      {
	case IND_none:
	  return ( IF_ACspild == value1 );
	case IND_A:
	  return ( IF_OA == value1 );
	case IND_B:
	  return ( IF_OB == value1 );
	case IND_C:
	  return ( (IF_OA == value1) && (IF_OB == value1) );
      }
    case IND_T:
      switch(IND_addr2)
      {
	case IND_none:
	  return ( IF_AC00 == value1 );
	case IND_A:
	  return ( IF_TA == value1 );
	case IND_B:
	  return ( IF_TB == value1 );
	case IND_C:
	  return ( (IF_TA == value1) && (IF_TB == value1) );
      }
    case IND_P:
      switch(IND_addr2)
      {
        case IND_none:
	  return 1;
	case IND_A:
	  return ( IF_PA == value1 );
	case IND_B:
	  return ( IF_PB == value1 );
	case IND_C:
	  return ( (IF_PA == value1) && (IF_PB == value1) );
      }
    case IND_Q:
      switch(IND_addr2)
      {
        case IND_none:
	  return 1;
	case IND_A:
	  return ( IF_QA == value1 );
	case IND_B:
	  return ( IF_QB == value1 );
	case IND_C:
	  return ( (IF_QA == value1) && (IF_QB == value1) );
      }
    case IND_R:
      switch(IND_addr2)
      {
        case IND_none:
	  return 1;
	case IND_A:
	  return ( IF_RA == value1 );
	case IND_B:
	  return ( IF_RB == value1 );
	case IND_C:
	  return ( (IF_RA == value1) && (IF_RB == value1) );
      }
    }
  }
  return 1;
}

static void print_indicator(char *text)
{
  fprintf(debug_fh, "%s: spild: %d T: %d OA: %d OB: %d TA: %d TB: %d PA: %d PB: %d QA: %d QB: %d RA: %d RB: %d\n",
	 text, spild, IF_AC00, IF_OA, IF_OB, IF_TA, IF_TB, IF_PA, IF_PB, IF_QA, IF_QB, IF_RA, IF_RB);
}

static void indicator_operation()
{
  int IND_oper = (OR&ONE33_34)>>SHIFT34;
  int IND_addr1 = (OR&ONE35_37)>>SHIFT37;
  int IND_addr2 = (OR&ONE38_39)>>SHIFT39;

  int shift;
  unsigned short value,mask;

  if(debug&DEBUGindicator)
  {
    fprintf(debug_fh, "indicator operation: oper: %d addr1: %d addr2: %d\n", IND_oper, IND_addr1, IND_addr2);
    print_indicator("Before indicator operation");
  }

  shift = 14-2*IND_addr1;
  if(shift==10) shift=8; /* IZ and IO both manipulates O */

  if(IND_oper == IND_I)
  {
    /* Indicate; transfer information to
       the indicator */

    value = IND_addr2<<shift;
    mask = ~value;
    switch(IND_addr1)
    {
      case IND_none:
        /* No indicator operation */
      case IND_K:
        /* Handled in Mode 4 */
	break;
      case IND_Z:
	IN = (IN&mask) | (value*IF_ACeq0);
	break;
      case IND_O:
	IN = (IN&mask) | (value*spild);
	break;
      case IND_T:
	IN = (IN&mask) | (value*IF_H00);
	break;
      case IND_P:
      case IND_Q:
      case IND_R:
        IN = (IN&mask) | ( (IND_addr2&H)<<shift );
	break;
    }
  }
  else if(IND_oper == IND_M)
  {
    /* Mark. Mark cell according to indicator */
    if(IND_addr1 == IND_none)
    {
      H |= 3;
      LI = (LI & ~ONE40_41) | IND_addr2;
    }
    else
    {
      LI = (LI & ~ONE40_41) | ( (((ind_ka<<13) | (ind_kb<<12) | IN)>>shift)&IND_addr2 );
    }
  }
  if(debug&DEBUGindicator) print_indicator("After  indicator operation");
}

/*
	Help functions for input/output:
*/

static int jLY()
{
  int i;
  /* Return 0 if character available */

  if((IF_BY8&&(!IF_BY9))||((!IF_BY8)&&IF_BY9))
  {
    /* Typewriter */
    if(typewriter_nchars>0)
    {
      BT=typewriter_char_table[0];
      typewriter_nchars--;
      for(i=0; i<typewriter_nchars; i++) typewriter_char_table[i]=typewriter_char_table[i+1];
      typewriter_wait(FALSE);
      return 0;
    }
    else
    {
      typewriter_wait(TRUE);
      return 1;
    }
  }
  else
  {
    /* Tape reader */
    if((reader_nchars-reader_offset)>0)
    {
      /* TODO: Check parity! */
      reader_parity_error = !check_parity((unsigned char) reader_char_table[reader_offset]);
      BL=remove_parity((unsigned char) reader_char_table[reader_offset]);
      if(BL == 127) reader_parity_error = 0;
      if(IF_BY8&&IF_BY9)
      {
	if(reader_parity_error)
	{
	  BL+=512;
	  reader_parity_error=0;
	}
      }
      reader_nchars--;
      for(i=0; i<reader_nchars; i++) reader_char_table[i]=reader_char_table[i+1];
      reader_char_table[reader_nchars]=0;
      reader_wait(FALSE);
      return 0;
    }
    else
    {
      reader_wait(TRUE);
      return 1;
    }
  }
}

static void drum_step()
{
  int extrastep=4;
  step_count+=extrastep;
  SY_count+=extrastep;
  clock_count+=extrastep;
  drum_count+=extrastep;
  disk_count+=extrastep;
}

void ModeLK()
{
  /*
  	Mode LK

	This microcode program is called each time
	a cell is ready from the drum
  */
  switch(MA)
  {
  case 1:
    Gs_TR_Add;
    			Gm_TA;
			Gm_AD1_til_TA;
    MA=2;
    break;
  case 2:
    Gs_blind;
    MA=3;
    break;
  case 3:
    Gs_TI0_41;
    			Gm_LI0_41_drum;
			FL_skriv_drum;
    MA=4;
    break;
  case 4:
    MA=5;
    break;
  case 5:
    MA=6;
    break;
  case 6:
    MA=7;
    break;
  case 7:
    MA=8;
    break;
  case 8:
    drum_step();
    Gs_stop_B_puls;
    			Gm_skift_B_A;
			Gm_TA_til_AD1;
    break;
  }
}

void ModeSK()
{
  /*
  	Mode SK

	This microcode program is called each time
	a cell is ready from the drum
  */
  switch(MA)
  {
  case 1:
    Gs_TR_Add;
    			Gm_TA;
			Gm_AD1_til_TA;
    MA=2;
    break;
  case 2:
                        FL_laes0_41_drum;
    MA=3;
    break;
  case 3:
    Gs_blind;
    MA=4;
    break;
  case 4:
    MA=5;
    break;
  case 5:
    Gs_LI0_41_drum;
    			Gm_TI0_41;
    MA=6;
    break;
  case 6:
    MA=7;
    break;
  case 7:
    MA=8;
    break;
  case 8:
    drum_step();
    Gs_stop_B_puls;
    			Gm_skift_B_A;
			Gm_TA_til_AD1;
    break;
  }
}

/* From DEMON-5 */

#define c39 6
#define MODULUS 100000

static void dassign(long *A, int *asize, long x)
{
  int i;
  if(x==0)
    *asize = 0;
  else
    *asize = c39-1;
  for(i=0;i<c39;i++) A[i]=0;
  A[*asize]=x;
}

static void dadd(long *A, int *asize, long *B, int bsize)
{
  int i,size;
  long cell,carry,a,b;
  size = (*asize);
  if(bsize>size) size=bsize;
  carry=0;
  for(i=0;i<=size;i++)
  {
    a=i<=(*asize)?A[i]:0;
    b=i<=bsize?B[i]:0;
    cell=a+b+carry;
    A[i]=cell%MODULUS;
    carry=cell/MODULUS;
  }
  *asize=size;
  if(carry>0)
  {
    A[*asize]=1;
    (*asize)++;
  }
}

static void ddivide(long *A, int *asize, long n)
{
  int i,first;
  long cell,carry;
  first=1;
  for(i=(*asize);i>=0;i--)
  {
    cell=A[i]+carry*MODULUS;
    carry=cell%n;
    cell=cell/n;
    if(first && cell>0)
    {
      *asize = i;
      first = 0;
    }
    A[i]=cell;
  }
}

static void dprintnum(long *A, int asize, int negative)
{
  int i;
  if(negative)
  {
    if(A[c39-1]>0)
      fprintf(debug_fh, "%5ld.", -A[c39-1]);
    else
      fprintf(debug_fh, "   -0.");
  }
  else
    fprintf(debug_fh, "%5ld.", A[c39-1]);
  fprintf(debug_fh, "%05ld", A[c39-2]);
  for(i=c39-3;i>=0;i--) fprintf(debug_fh, " %05ld",A[i]);
}

static void dneg(GIERword *c1, GIERword *c2)
{
  *c1 = (~((*c1) & ONE0_39))&ONE0_39;
  *c2 = (~((*c2) & ONE0_39))&ONE1_39;
  *c2 += ONE39;
  if((*c2)&ONE0)
  {
    *c1 += ONE39;
    *c2 = (*c2)&ONE1_39;
  }
}

static void dprint(char *txt,GIERword c1,GIERword c2)
{
  int negative;
  long A[c39],SUM[c39];
  int asize,ssize,i;
  GIERword bit;
  fprintf(debug_fh, "%s: ", txt);
  if( ((c1&ONE0_39)==ONE0) &&
      ((c2&ONE0_39)==0))
  {
    fprintf(debug_fh,"-1.00000 00000 00000 00000 00000");
  }
  else
  {
    negative = (c1&ONE0)!=0;
    if(negative) dneg(&c1,&c2);
    dassign(A,&asize,512);
    dassign(SUM,&ssize,0);
    for(i=1;i<=78;i++)
    {
      ddivide(A,&asize,2);
      if(i<40)
	bit=c1&(ONE0>>i);
      else
	bit=c2&(ONE0>>(i-39));
      if(bit)
	dadd(SUM,&ssize,A,asize);
    }
    dprintnum(SUM,ssize,negative);
  }
  fprintf(debug_fh, "\n");
}

void dptest()
{
  if(OT==59 && h==0 && (LI&ONE0_41)==
      (Opcode(Op_GR) | Address1(837) | Right(Opcode(Op_GM) | Address1(838)))) dprint("t",AC,MQ);
  if(OT==62 && h==1 && (LI&ONE0_41)==
      (Opcode(Op_PP) | Address1(36) | Right(Opcode(Op_PP) | Address1(1023) | p_relative))) dprint("b",AC,MQ);
}

void Mode1()
{
  /*
	Mode 1:

	Load word.
	Address calculation.
	Test indicator, if this instruction is to be skipped.

  */
  time_t time1;
  microdump("Mode1:");
  switch(MA)
  {
  case 1:
    /*
    	Check for buttons:
    */
    if(HP_button_pressed && ((BY&512) == 0))
    {
      wait_drum();
      HP_button_pressed=0;
      BY = BY|512;
      if(debug&DEBUGinterface) fprintf(debug_fh, "HP button\n");
      Mode=Mode5;
      MA=1;
      return;
    }
    else if(normal_stop_pressed)
    {
      wait_drum();
      GIER_stop();
      normal_stop_pressed=0;
      return;
    }
    else if(normal_singlestep_pressed)
    {
      normal_singlestep_pressed=0;
      normal_stop_pressed=1; /* stop next time */
    }
    /*
    fprintf(debug_fh, "OT: %d Spill(%d) OA(%d) OB(%d) TA(%d) TB(%d) PA(%d) PB(%d) QA(%d) QB(%d) RA(%d) RB(%d) %s ", OT,
	 spild, IF_OA, IF_OB, IF_TA, IF_TB, IF_PA, IF_PB, IF_QA, IF_QB, IF_RA, IF_RB,
	 h?"h":" ");
    dumpword(debug_fh, Ferrit[OT]);
    fprintf(debug_fh, "\n");
    fprintf(debug_fh, "%5d %1d %5d\n", OT, spild, IN*4);
    */
    Gs_OT;
    Gs_o10_41;
    Gs_Addition;
    			Gm_AD1;
			Gm_H10_39;
    MA=2;
    break;
  case 2:
    Gs_AD1;
    Gs_o20_41;
    			Gm_AD2;
			Gm_MD20_39;
			FL_laes0_41;
    MA=3;
    break;
  case 3:
    Gs_AD2_skraa;
    			Gm_MD10_19;
			FL_skriv;
    MA=4;
    break;
  case 4:
    Gs_SR;
    Gs_o20_41;
    			Gm_AD2;
			Gm_OR30_39;
    MA=5;
    break;
  case 5:
    if(debug&DEBUGexecute)
    {
      double x;
      int exponent;
      fprintf(debug_fh, "\n   AC: ");
      printword((AC&~ONE40_41)|(H&ONE40_41));
      fprintf(debug_fh, "   MQ: ");
      printword(MQ);
      
      fprintf(debug_fh, "   RF: ");

      if( (AC&ONE10)==0 )
      {
	x=((double)(AC&ONE10_39))/((double)ONE11);
      }
      else
      {
	x=-(((double)((-AC)&ONE10_39))/((double)ONE11));
      }
      if( (MQ&ONE0)==0 )
      {
	exponent = (int) ((MQ&ONE0_9)>>SHIFT9);
      }
      else
      {
	exponent = ((int) ((MQ&ONE0_9)>>SHIFT9))-1024;
      }
      for(;exponent>0;exponent--) x = x*2.0;
      for(;exponent<0;exponent++) x = x*0.5;

      fprintf(debug_fh, "%.10lg\n",x);
      /* dprint("   RM",AC,MQ); */
      fprintf(debug_fh, "   s: %d     p: %d     tk: %d   tg: %d   by: %d\n", SR, AD0, TK, TG, BY);
      print_indicator("Mode 1");
    }
    if( (debug&DEBUGexecute) || ((debug&DEBUGdrum) && (debug&DEBUGbuffer)))
    {
      if(caddress[OT] != -1)
      {
	fprintf(debug_fh, "c%d: ",caddress[OT]);
      }
      fprintf(debug_fh, "Execute[%d%s]: ",OT,h?"h":"");
      dumpword(debug_fh, LI);
      time1 = time(NULL);
#ifdef WINDOWS
      fprintf(debug_fh, "   clock: %I64d %I64d %ld", clock_count, clock_count-last_execute_clock_count, time1-start_time);
#else
      fprintf(debug_fh, "   clock: %lld %lld %ld", clock_count, clock_count-last_execute_clock_count, time1-start_time);
#endif
      last_execute_clock_count=clock_count;
      if(caddress[OT] != -1)
      {
	if(cnames[caddress[OT]].text != NULL)
	  fprintf(debug_fh, " ; %s", cnames[caddress[OT]].text);
      }
      fprintf(debug_fh, "\n");
    }
    if(debug&DEBUGexecute)
    {
      if(h?(((LI<<10)&ONE20_25)>>SHIFT25==34):((LI&ONE20_25)>>SHIFT25==34))
      {
#ifdef WINDOWS
	fprintf(debug_fh, "clock since last HK: %I64d\n", clock_count-last_clock_count_HK);
#else
	fprintf(debug_fh, "clock since last HK: %lld\n", clock_count-last_clock_count_HK);
#endif
	last_clock_count_HK=clock_count;
      }
      /* dptest(); */
      if((OT==130)&&(LI==(Opcode(Op_NC) | Address1(844) | Address2(3) | Indirmark | Smark )))
      {
	/* Execute[130]: ncn (844) t+3 */
	coredump();
      }
    }
    if(!IF_LI40)
    {
      Gs_LI0_9;
      Gs_LI10_19;
      Gs_LI20_41;
      Gs_0h;
      			Gm_H00_9;
			Gm_TD;
			Gm_OR20_41;
			Gm_tael_i_OT;
      MA=8;
    }
    else if(IF_LI40 && !IF_h)
    {
      Gs_LI0_9;
      Gs_H10_19;
      Gs_LI20_29;
      Gs_LI40_41;
      Gs_1h;
      			Gm_H00_9;
			Gm_TD;
			Gm_OR20_29;
			Gm_OR40_41;
      MA=8;
    }
    else
    {
      Gs_LI10_19;
      Gs_LI30_39;
      Gs_Linie30_39_Linie_20_29;
      Gs_LI40_41;
      Gs_0h;
      			Gm_TD;
			Gm_OR20_29;
			Gm_OR40_41;
			Gm_tael_i_OT;
      MA=6;
    }
    break;
  case 6:
    Gs_TD_skraa;
    			Gm_H00_9;
    MA=7;
    break;
  case 7:
    Gs_H10_19;
    			Gm_TD;
    MA=8;
    break;
  case 8:
    if(debug&DEBUGtime)
    {
      timing_statistics[last_instruction] += (clock_count - last_clock_count);
      last_clock_count = clock_count;
      last_instruction = AD1;
    }
    if(IF_q)
    {
      Gs_o10_19;
      Gs_TD_skraa;
      			Gm_H10_19;
			Gm_MD00_9;
      MA=9;
    }
    else if((!IF_q)&&(IF_r)&&(!IF_s))
    {
      Gs_o10_19;
      Gs_AD1;
      			Gm_H10_19;
			Gm_MD00_9;
      MA=13;
    }
    else if((!IF_q)&&(!IF_r)&&(IF_s))
    {
      Gs_o10_19;
      Gs_AD2;
      			Gm_H10_19;
			Gm_MD00_9;
      MA=13;
    }
    else if((!IF_q)&&(IF_r)&&(IF_s))
    {
      Gs_o10_19;
      Gs_AD0;
      			Gm_H10_19;
			Gm_MD00_9;
      MA=13;
    }
    else if((!IF_q)&&(!IF_r)&&(!IF_s))
    {
      Gs_o10_19;
      Gs_o0_9;
      			Gm_H10_19;
			Gm_MD00_9;
      MA=13;
    }
    break;
  case 9:
    if(IF_B)
    {
    			FL_laes10_41;
      MA=10;
    }
    else
    {
      MA=1;
    }
    break;
  case 10:
    Gs_Adder00_19;
    			Gm_LI0_9;
			FL_skriv;
    MA=11;
    break;
  case 11:
    Gs_Adder00_19;
    			Gm_H00_9;
    MA=12;
    break;
  case 12:
    if( (IF_r) && (!IF_s) )
    {
      Gs_AD1;
      			Gm_MD00_9;
      MA=13;
    }
    else if( (!IF_r) && (IF_s) )
    {
      Gs_AD2;
      			Gm_MD00_9;
      MA=13;
    }
    else if( (IF_r) && (IF_s) )
    {
      Gs_AD0;
      			Gm_MD00_9;
      MA=13;
    }
    else if( (!IF_r) && (!IF_s) )
    {
      Gs_o0_9;
      			Gm_MD00_9;
      MA=13;
    }
    break;
  case 13:
    if(!IF_B)
    {
      MA=1;
    }
    else if(IF_i&&(!IF_r)&&IF_s)
    {
      Gs_AD2;
      			Gm_AD1;
      MA=15;
    }
    else if(IF_i&&(IF_r || (!IF_s)))
    {
      MA=20;
    }
    else if((!IF_i)&&IF_S)
    {
      Gs_o0_41;
      			Gm_AC00_39;
      MA=14;
    }
    else if((!IF_i)&&(!IF_S))
    {
      MA=14;
    }
    break;
  case 14:
    if(!IF_d)
    {
      Gs_Adder00_19;
      			Gm_AD1;
			Gm_H20_39;
			Gm_saetTL_0bc;
			Gm_step;
      Gs_Mode2;
      MA=1;
    }
    else
    {
      Gs_Adder00_19;
      			Gm_MD00_9;
			Gm_H20_39;
			Gm_saetTL_0bc;
			Gm_step;
      Gs_Mode2;
      MA=1;
    }
    if(debug&DEBUGstat)
    {
      statistics[((OR&ONE20_25)>>SHIFT25)|((OR&ONE41)<<(SHIFT35-SHIFT41))]++;
    }
    break;
  case 15:
    Gs_Adder00_19;
    			Gm_H00_9;
			FL_laes0_41;
    MA=16;
    break;
  case 16:
    Gs_TD;
    			Gm_H10_19;
			Gm_step;
    MA=18;
    break;
  case 18:
    Gs_LI10_19;
    			Gm_TD;
    MA=19;
    break;
  case 19:
    Gs_TD_skraa;
    			Gm_AD2;
    MA=20;
    break;
  case 20:
    if((!IF_r)&&IF_s)
    {
      Gs_H00_9;
      Gs_H10_19;
      			Gm_AD1;
			Gm_TD;
      MA=21;
    }
    else if(IF_r||(!IF_s))
    {
      Gs_Adder00_19;
      			Gm_AD1;
      MA=21;
    }
    break;
  case 21:
			Gm_step;
    			FL_laes0_41;
    MA=23;
    break;
  case 23:
    Gs_o0_9;
    Gs_o10_19;
    			Gm_MD00_9;
			Gm_H10_19;
    MA=24;
    break;
  case 24:
    Gs_LI0_9;
    Gs_LI20_29;
    			Gm_H00_9;
			Gm_OR27_29;
    MA=8;
    break;
  default:
    PANIK("Unknown MA in Mode 1");
  }
  after_MA();
}

int rdrand_step (GIERword *rand)
{
  unsigned char ok;

  asm volatile ("rdrand %0; setc %1"
	      : "=r" (*rand), "=qm" (ok));
  return (int) ok;
}

int rdrand(unsigned int retries, GIERword *rand)
{
  unsigned int count= 0;

  while ( count <= retries )
  {
    if ( rdrand_step(rand) )
    {
      return 1;
    }
    ++count;
  }
  return 0;
}

static int lastOB=0;

void Mode2()
{
  int i;
  int zj_command, zj_parameter;
  /*
	Execute opcode
  */
  microdump("Mode2:");
  TO_error=0;
  if(debug&DEBUGmicrostep) fprintf(debug_fh, "Mode 2 opcode: %d\n", (OR&ONE20_25)>>SHIFT25);
  switch((OR&ONE20_25)>>SHIFT25)
  {
  case 0: /* QQ */
    switch(MA)
    {
    case 1:
      Gs_AD1;
      Gs_Mode4;
      			Gm_H00_9;
			Gm_step;
      MA=2;
      break;
    }
    break;
  case 1: /* ZQ */
    switch(MA)
    {
    case 1:
      clock_count=0;
      Gs_AD1;
      Gs_Mode4;
      			Gm_H00_9;
			Gm_stop;
			Gm_step;
      MA=2;
      break;
    }
    break;
  case 2: /* AR */
  case 3: /* SR */
  case 4: /* AN */
  case 5: /* SN */
    switch(MA)
    {
    case 1:
      if(debug&(DEBUGexecute|DEBUGdrum))
      {
	int i;
	i=cnames[65].caddress;
	if(i != -1)
	{
	  if(OT==(i+3) && LI==4363686936576ULL) segmentdump();
	}
      }
      if(IF_OR41)
      {
        Gs_MQ0_9;
	Gs_o10_41;
	Gs_Subtraktion;
			Gm_AD2;
			Gm_MD10_39;
			FL_laes0_41;
	MA=2;
      }
      else
      {
        Gs_Addition;
	Gs_Mode3;
			Gm_step;
			FL_laes0_41;
	MA=16;
      }
      if(debug&DEBUGexecute)
      {
	fprintf(debug_fh, "AR/SR/AN/SN[%d]: ",AD1);
	printword(LI);
      }
      break;
    case 2:
      if(IF_S)
      {
        Gs_AC00_39H40_41;
			Gm_MQ0_39;
			Gm_step;
	MA=4;
      }
      else
      {
        Gs_MQ0_9;
	Gs_o10_41;
			Gm_H00_9;
			Gm_H10_39;
	MA=3;
      }
      break;
    case 3:
      if(!IF_ACstareq0)
      {
        Gs_AC00_39H40_41;
	Gs_1b;
			Gm_MQ0_39;
	MA=4;
      }
      else
      {
        Gs_AC00_39H40_41;
			Gm_MQ0_39;
        MA=4;
      }
      break;
    case 4:
      Gs_LI0_9;
      Gs_LI10_39;
      Gs_LI40_41;
      			Gm_MD00_9;
			Gm_AC10_39;
			Gm_H40_41;
      MA=5;
      break;
    case 5:
      if(!IF_AC10)
      {
        Gs_o0_9;
			Gm_AC00_9;
	MA=6;
      }
      else
      {
        		Gm_AC00_9;
	MA=6;
      }
      break;
    case 6:
      if(IF_b)
      {
        Gs_MD0_9;
        Gs_o10_14o19;
			Gm_AD1;
			Gm_TD;
	MA=7;
      }
      else
      {
        Gs_MD0_9;
	Gs_1c;
	Gs_o10_19;
			Gm_AD1;
			Gm_TD;
	MA=16;
      }
      break;
    case 7:
      if(!IF_ACstareq0)
      {
        Gs_Adder00_19;
			Gm_H00_9;
	MA=8;
      }
      else
      {
        Gs_o10_19;
	Gs_AD2;
			Gm_TD;
			Gm_AD1;
	MA=16;
      }
      break;
    case 8:
      if(IF_H00)
      {
        Gs_H0_9;
	Gs_1c;
			Gm_MD00_9;
	MA=9;
      }
      else
      {
        Gs_TD_skraa;
			Gm_MD00_9;
	MA=11;
      }
      break;
    case 9:
      if(IF_c)
      {
        Gs_o0_9;
			Gm_H00_9;
	MA=10;
      }
      else
        PANIK("AR, step 9");
      break;
    case 10:
      if(IF_c)
      {
        Gs_AD1;
			Gm_AD2;
	MA=7;
      }
      else
	PANIK("AR, step 10");
      break;
    case 11:
      Gs_AD2;
      			Gm_AD1;
      MA=12;
      break;
    case 12:
      if(IF_b)
      {
        Gs_H00_9;
			Gm_AD2;
	MA=13;
      }
      else
      {
        Gs_H00_9;
	Gs_Mode4;
	Gs_spild;
			Gm_AC00_9;
			Gm_step;
	MA=2;
      }
      break;
    case 13:
      if(IF_b)
      {
        Gs_Adder00_19;
			Gm_H00_9;
	MA=14;
      }
      else
        PANIK("AR, step 13");
      break;
    case 14:
      if(!IF_H00)
      {
        Gs_o10_19;
			Gm_TD;
	MA=16;
      }
      else
      {
        Gs_AD2_skraa;
			Gm_TD;
	MA=15;
      }
      break;
    case 15:
      if(IF_c)
      {
        Gs_MQ0_39;
			Gm_H00_39;
	MA=17;
      }
      else
      {
        Gs_AC00_39H40_41;
			Gm_H00_39;
	MA=17;
      }
      break;
    case 16:
      if(IF_b)
      {
        Gs_o0_41;
			Gm_H00_39;
	MA=19;
      }
      else if(IF_c)
      {
        Gs_o0_41;
	Gs_1b;
			Gm_H00_39;
	MA=19;
      }
      else
        PANIK("AR, step 16");
      break;
    case 17:
      if(!IF_TDeq0)
      {
        Gs_H00_39;
			Gm_H1_39hs;
			Gm_tael_i_TD;
			Gm_Linie00_H00_H0;
	MA=18;
      }
      else
      {
        MA=19;
      }
      break;
    case 18:
      if(!IF_TDeq0)
      {
        Gs_H00_39;
			Gm_H1_39hs;
			Gm_tael_i_TD;
			Gm_Linie00_H00_H0;
	MA=17;
      }
      else
      {
        MA=19;
      }
      break;
    case 19:
      if(IF_c)
      {
        Gs_AC00_39H40_41;
	Gs_Addition;
			Gm_MD00_39;
	MA=24;
      }
      else
      {
        Gs_H00_39;
	Gs_Addition;
			Gm_MD00_39;
        MA=20;
      }
      break;
    case 20:
      if(IF_b)
      {
        Gs_MQ0_39;
			Gm_H00_39;
	MA=24;
      }
      else
        PANIK("AR, step 20");
      break;
    case 22:
      if(IF_b)
      {
        Gs_Adder00_39;
			Gm_AC00_39;
	MA=23;
      }
      else
      {
        Gs_Adder00_39;
			Gm_H00_9;
			Gm_AC10_39;
	MA=12;
      }
      break;
    case 23:
      Gs_Mode3;
      			Gm_saetTL_0bc;
			Gm_step;
      MA=1;
      break;
    case 24:
      if(IF_plus)
      {
        Gs_blind;
	MA=22;
      }
      else
      {
        Gs_Subtraktion;
			Gm_step;
	MA=22;
      }
      break;
    }
    break;
  case 6: /* AC */
  case 7: /* SC */
    switch(MA)
    {
    case 1:
      Gs_MD0_9;
      			Gm_H00_9;
			FL_laes0_41;
      MA=6;
      if(debug&DEBUGexecute)
      {
        fprintf(debug_fh, "AC/SC[%d]: ",AD1);
	printword(LI);
      }
      break;
    case 6:
      if(!IF_OR25)
      {
        Gs_Addition;
	MA=10;
      }
      else
      {
        Gs_Subtraktion;
	MA=10;
      }
      break;
    case 10:
      Gs_AC00_39H40_41;
      			Gm_MD00_39;
      MA=11;
      break;
    case 11:
      if(!IF_d)
      {
        Gs_LI0_41;
			Gm_H00_41;
			Gm_step;
	MA=16;
      }
      else
      {
        Gs_o10_41;
			Gm_H10_39;
			Gm_step;
	MA=17;
      }
      break;
    case 16:
      if(!IF_M)
      {
        Gs_Adder00_39;
			Gm_LI0_39;
			FL_laes40_41;
	MA=18;
      }
      else
      {
        Gs_Adder00_39;
			Gm_LI0_39;
			Gm_IO;
			FL_skriv;
	MA=18;
      }
      break;
    case 17:
      Gs_Adder00_19;
      			Gm_LI0_9;
			FL_laes10_41;
      MA=18;
      break;
    case 18:
      Gs_Adder00_19;
      			Gm_H00_9;
      MA=19;
      break;
    case 19:
      Gs_Mode4;
      			Gm_spild;
      MA=10;
      break;
    }
    break;
  case 8: /* MB */
  case 9: /* AB */
    switch(MA)
    {
    case 1:
      Gs_AC00_39H40_41;
      			Gm_H00_39;
			FL_laes0_41;
      MA=7;
      if(debug&DEBUGexecute)
      {
        fprintf(debug_fh, "MB/AB[%d]: ",AD1);
	printword(LI);
      }
      break;
    case 7:
      Gs_Addition;
      			Gm_step;
      MA=10;
      break;
    case 10:
      if(!IF_d)
      {
        Gs_LI0_39;
	Gs_LI40_41;
			Gm_MD00_39;
			Gm_H40_41;
	MA=11;
      }
      else
      {
        Gs_o10_41;
			Gm_MD10_39;
	MA=11;
      }
      break;
    case 11:
      if(!IF_X)
      {
        Gs_H00_39;
	Gs_MD0_39;
			Gm_AC00_39;
	MA=14;
      }
      else
      {
        Gs_H00_39;
	Gs_MD0_39;
			Gm_AC00_39;
	MA=15;
      }
      break;
    case 14:
      if(!IF_OR25)
      {
        Gs_AC00_9;
	Gs_Mode4;
			Gm_H00_9;
			Gm_step;
	MA=2;
      }
      else
      {
        Gs_Adder00_39;
			Gm_H00_39;
	MA=16;
      }
      break;
    case 15:
      Gs_Adder00_39;
      			Gm_H00_39;
      MA=16;
      break;
    case 16:
      Gs_AC00_39H40_41;
      Gs_Subtraktion;
      			Gm_MD00_39;
			Gm_step;
      MA=18;
      break;
    case 18:
      if(!IF_OR25)
      {
        Gs_Adder00_39;
			Gm_H00_39;
			Gm_step;
	MA=23;
      }
      else
      {
        Gs_Adder00_39;
			Gm_MD00_39;
	MA=21;
      }
      break;
    case 21:
      			Gm_H00_39;
      MA=22;
      break;
    case 22:
      if(!IF_X)
      {
        Gs_MD0_39;
			Gm_AC00_39;
	MA=24;
      }
      else
      {
        Gs_MD0_39;
			Gm_AC00_39;
	MA=23;
      }
      break;
    case 23:
      Gs_Adder00_39;
      			Gm_MQ0_39;
      MA=24;
      break;
    case 24:
      Gs_AC00_9;
      Gs_Mode4;
      			Gm_H00_9;
			Gm_step;
      MA=2;
      break;
    }
    break;
  case 10: /* MT */
    switch(MA)
    {
    case 1:
      if(!IF_d)
      {
        Gs_o0_41;
			Gm_H00_39;
			FL_laes0_41;
	MA=16;
      }
      else
      {
        Gs_o0_41;
			Gm_H00_39;
	MA=24;
      }
      break;
    case 16:
      Gs_blind;
      			Gm_step;
      MA=18;
      break;
    case 18:
      Gs_LI0_9;
      Gs_LI40_41;
      			Gm_MD00_9;
			Gm_H40_41;
      MA=24;
      break;
    case 19:
      Gs_AC00_39H40_41;
      Gs_Addition;
      			Gm_MD00_39;
			Gm_step;
      MA=22;
      break;
    case 20:
      Gs_AC00_39H40_41;
      Gs_Subtraktion;
      			Gm_MD00_39;
			Gm_step;
      MA=22;
      break;
    case 22:
      Gs_Adder00_19;
      Gs_Adder20_39;
      			Gm_H00_9;
			Gm_AC10_39;
      MA=23;
      break;
    case 23:
      Gs_H00_9;
      Gs_Mode4;
      			Gm_AC00_9;
			Gm_spild;
      MA=2;
      break;
    case 24:
      if(!IF_MD0)
      {
        Gs_blind;
	MA=19;
      }
      else
      {
        Gs_blind;
	MA=20;
      }
      break;
    }
    break;
  case 11: /* MK */
    switch(MA)
    {
    case 1:
      if(IF_OR41)
      {
        Gs_MQ0_9;
	Gs_o10_14o19;
	Gs_Addition;
			Gm_AD2;
			Gm_TD;
			FL_laes0_41;
	MA=2;
      }
      else
      {
        Gs_o0o2_41;
        Gs_39_TD;
	Gs_Addition;
	Gs_Mode3;
			Gm_H00_39;
			Gm_oH00;
			Gm_step;
			FL_laes0_41;
	MA=20;
      }
      break;
    case 2:
      Gs_AC00_39H40_41;
      			Gm_MQ0_39;
      MA=3;
      break;
    case 3:
      			Gm_tael_i_TD;
      MA=4;
      break;
    case 4:
      Gs_LI0_39;
      Gs_LI40_41;
      			Gm_MD0_39;
			Gm_H40_41;
      MA=5;
      break;
    case 5:
      if(!IF_MD10)
      {
        Gs_o0_9;
	Gs_MD10_39;
			Gm_H0_9vs;
			Gm_Linie0_H00;
			Gm_H10_38vs;
			Gm_oH39;
        MA=6;
      }
      else
      {
        Gs_MD10_39;
			Gm_H0_9vs;
			Gm_H10_38vs;
			Gm_oH39;
			Gm_Linie0_H00;
	MA=6;
      }
      break;
    case 6:
      Gs_MD0_9;
      			Gm_AD1;
      MA=7;
      break;
    case 7:
      Gs_H00_39;
      			Gm_MD00_39;
      MA=8;
      break;
    case 8:
      Gs_o0_41;
      			Gm_H00_39;
      MA=24;
      break;
    case 9:
      Gs_blind;
      MA=10;
      break;
    case 10:
      if((!IF_TDeq0)&&IF_MQ38&&IF_b)
      {
        Gs_Adder00_39;
			Gm_H1_39hs;
                        Gm_Linie00_H00_H0;
			Gm_MQ39_MQ0;
			Gm_MQ1_39hs;
			Gm_tael_i_TD;
	MA=9;
      }
      else if((!IF_TDeq0)&&(!IF_MQ38)&&IF_b)
      {
        Gs_Adder00_39;
			Gm_H1_39hs;
                        Gm_Linie00_H00_H0;
			Gm_MQ39_MQ0;
			Gm_MQ1_39hs;
			Gm_tael_i_TD;
	MA=11;
      }
      else if(IF_TDeq0)
      {
        Gs_Adder00_39;
	Gs_Subtraktion;
			Gm_H1_39hs;
                        Gm_Linie00_H00_H0;
			Gm_MQ39_MQ0;
			Gm_MQ1_39hs;
	MA=13;
      }
      else
        PANIK("MK, step 10");
      break;
    case 11:
      if((!IF_TDeq0)&&IF_MQ38&&IF_b)
      {
        Gs_H00_39;
			Gm_H1_39hs;
			Gm_Linie00_H00_H0;
			Gm_MQ39_MQ0;
			Gm_MQ1_39hs;
			Gm_tael_i_TD;
        MA=9;
      }
      else if((!IF_TDeq0)&&(!IF_MQ38)&&IF_b)
      {
        Gs_H00_39;
			Gm_H1_39hs;
			Gm_Linie00_H00_H0;
			Gm_MQ39_MQ0;
			Gm_MQ1_39hs;
			Gm_tael_i_TD;
        MA=11;
      }
      else if(IF_TDeq0)
      {
        Gs_H00_39;
	Gs_Subtraktion;
			Gm_MQ39_MQ0;
			Gm_MQ1_39hs;
			Gm_H1_39hs;
			Gm_Linie00_H00_H0;
	MA=13;
      }
      else
        PANIK("MK, step 11");
      break;
    case 13:
      if(IF_MQ39)
      {
        Gs_blind;
	MA=14;
      }
      else
      {
        Gs_Addition;
	MA=15;
      }
      break;
    case 14:
      if(IF_OR41)
      {
        Gs_Adder00_39;
	Gs_Addition;
			Gm_MQ0_39;
	MA=20;
      }
      else
      {
        Gs_Adder00_39;
	Gs_Addition;
			Gm_MD00_39;
	MA=16;
      }
      break;
    case 15:
      if(IF_OR41)
      {
        Gs_H00_39;
			Gm_MQ0_39;
	MA=20;
      }
      else
      {
        Gs_H00_39;
			Gm_MD00_39;
	MA=16;
      }
      break;
    case 16:
      if(IF_b)
      {
        Gs_AC00_39H40_41;
			Gm_H00_39;
	MA=17;
      }
      else
        PANIK("MK, step 16");
      break;
    case 17:
      			Gm_MQ1_39hs;
			Gm_MQ39_MQ0;
      MA=18;
      break;
    case 18:
      if(IF_b)
      {
        Gs_Adder00_39;
			Gm_H00_9;
			Gm_AC10_39;
	MA=19;
      }
      else
        PANIK("MK, step 18");
      break;
    case 19:
      Gs_H00_9;
      Gs_Mode4;
      			Gm_AC00_9;
			Gm_spild;
			Gm_saetTL_0bc;
			Gm_step;
      MA=2;
      break;
    case 20:
      Gs_AD1;
      			Gm_MD00_9;
			Gm_MD10_39;
      MA=21;
      break;
    case 21:
      if(IF_MQ9eqMQ10)
      {
        Gs_AD2;
	Gs_o10_41;
			Gm_H00_9;
			Gm_H10_39;
	MA=22;
      }
      else if((!IF_MQ9eqMQ10)&&IF_b)
      {
        Gs_AD2;
			Gm_H00_9;
			Gm_H10_39;
			Gm_MQ1_39hs;
			Gm_step;
	MA=22;
      }
      else
        PANIK("MK step 21");
      break;
    case 22:
      if(IF_MQ9eqMQ10)
      {
        Gs_MQ0_39;
	Gs_Mode3;
			Gm_AC00_39;
			Gm_saetTL_0bc;
			Gm_step;
	MA=6;
      }
      else if((!IF_MQ9eqMQ10)&&IF_b)
      {
        Gs_Adder00_19;
			Gm_H00_9;
			Gm_MQ1_39hs;
	MA=23;
      }
      else
	PANIK("MK, step 22");
      break;
    case 23:
      Gs_o0_9;
      Gm_MD00_9;
      MA=22;
      break;
    case 24:
      if(IF_MQ39)
      {
	Gs_1b;
	Gm_tael_i_TD;
	MA=10;
      }
      else
      {
	Gs_1b;
	Gm_tael_i_TD;
	MA=11;
      }
      break;
    }
    break;
  case 12: /* ML */
    switch(MA)
    {
      case 1:
	Gs_AC00_39H40_41;
	Gs_Addition;
	Gs_39_TD;
	Gs_Mode3;
	Gm_H00_39;
	Gm_step;
	FL_laes0_41;
	MA=20;
	if(debug&DEBUGexecute)
	{
	  fprintf(debug_fh, "ML[%d]: ",AD1);
	  printword(LI);
	}
	break;
      case 18:
	Gs_Adder00_39;
	Gm_H00_39;
	Gm_MQ1_39hs;
	Gm_0_MQ0;
	MA=23;
	break;
      case 19:
	if(!IF_TDeq0)
	{
	  Gs_Adder00_39;
	  Gm_H1_39hs;
	  Gm_Linie00_H00_H0;
	  Gm_Linie39_MQ0;
	  Gm_MQ1_39hs;
	  MA=24;
	}
	else
	{
	  Gs_Adder00_39;
	  Gs_Subtraktion;
	  Gm_H1_39hs;
	  Gm_Linie00_H00_H0;
	  Gm_Linie39_MQ0;
	  Gm_MQ1_39hs;
	  MA=21;
	}
	break;
      case 20:
	if(!IF_TDeq0)
	{
	  Gs_H00_39;
	  Gm_H1_39hs;
	  Gm_Linie00_H00_H0;
	  Gm_Linie39_MQ0;
	  Gm_MQ1_39hs;
	  MA=24;
	}
	else
	{
	  Gs_H00_39;
	  Gs_Subtraktion;
	  Gm_H1_39hs;
	  Gm_Linie00_H00_H0;
	  Gm_Linie39_MQ0;
	  Gm_MQ1_39hs;
	  MA=21;
	}
	break;
      case 21:
	if(IF_MQ39)
	{
	  MA=18;
	}
	else
	{
	  MA=22;
	}
	break;
      case 22:
	Gm_MQ1_39hs;
	Gm_0_MQ0;
	MA=23;
	break;
      case 23:
	Gs_H00_39;
	Gs_Mode4;
	Gm_AC00_39;
	Gm_spild;
	Gm_step;
	MA=2;
	break;
      case 24:
	if(IF_MQ39)
	{
	  Gm_tael_i_TD;
	  MA=19;
	}
	else
	{
	  Gm_tael_i_TD;
	  MA=20;
	}
	break;
    }
    break;
  case 13: /* DK */
  case 14: /* DL */
    switch(MA)
    {
    case 1:
      if(!IF_OR25)  /* if DL */
      {
        Gs_AC00_39H40_41;
	Gs_39_TD;
	Gs_Subtraktion;
	Gs_Mode3;
			Gm_H00_39;
			Gm_step;
			FL_laes0_41;
	MA=20;
      }
      else
      {
        Gs_AC00_39H40_41;
	Gs_Subtraktion;
			Gm_H00_39;
			FL_laes0_41;
	MA=2;
      }
      if(debug&DEBUGexecute)
      {
        fprintf(debug_fh, "DK/DL[%d]: ",AD1);
        printword(LI);
      }
#ifdef STRANGE
      if(IF_OR41 && (((OR&ONE20_25)>>SHIFT25)==13))
      {
	/* DKF */
	int ea,eb,ediff;
	DKFa = (MQ&ONE0_9)|(AC&ONE10_39);
	DKFb = LI;
      }
#endif
      break;
    case 2:
      if(!IF_OR41)
      {
        Gs_o0_41;
	Gs_39_TD;
	Gs_Mode3;
			Gm_MQ0_39;
			Gm_step;
	MA=21;
      }
      else
      {
        Gs_o10_14o19;
			Gm_TD;
	MA=3;
      }
      break;
    case 3:
      Gs_o0_41;
      Gs_1b;
      			Gm_AC00_39;
      MA=4;
      break;
    case 4:
      Gs_LI0_9;
      Gs_LI10_39;
      Gs_LI40_41;
      			Gm_AD2;
			Gm_AC10_39;
			Gm_H40_41;
      MA=5;
      break;
    case 5:
      if(!IF_AC10)
      {
        Gs_o0_9;
	Gs_AC10_39H40_41;
			Gm_MD00_9;
			Gm_MD10_39;
	MA=6;
      }
      else
      {
        Gs_AC10_39H40_41;
			Gm_MD00_9;
			Gm_MD10_39;
	MA=6;
      }
      break;
    case 6:
      if(!IF_ACeq0)
      {
        Gs_MQ0_9;
	Gs_o10_41;
			Gm_AD1;
			Gm_MQ10_39;
        MA=24;
      }
      else
      {
        Gs_o0o2_9;
	Gs_o10_41;
	Gs_Mode3;
			Gm_H0_9vs;
			Gm_Linie0_H00;
			Gm_MQ10_39;
			Gm_step;
	MA=8;
      }
      break;
    case 8:
      Gs_Adder00_39;
      Gs_Subtraktion;
      			Gm_H0_38vs;
			Gm_Linie0_H00;
			Gm_MQ0_H39strange;
			Gm_MQ0_38vs;
			Gm_1_MQ39;
      MA=9;
      break;
    case 9:
      Gs_H00_39;
      			Gm_AC00_39;
      MA=10;
      break;
    case 10:
      if(!IF_TDeq0)
      {
        Gs_Adder00_39;
			Gm_H0_38vs;
			Gm_Linie0_H00;
			Gm_MQ0_H39strange;
			Gm_tael_i_TD;
	MA=11;
      }
      else
      {
        Gs_Adder00_39;
			Gm_H00_39;
	MA=12;
      }
      break;
    case 11:
      if(IF_H00eqMD0)
      {
	Gs_H00_39;
			Gm_AC00_39;
			Gm_MQ0_38vs;
			Gm_1_MQ39;
	MA=10;
      }
      else
      {
	Gs_AC00_39H40_41;
			Gm_H0_38vs;
			Gm_MQ0_H39;
			Gm_Linie0_H00;
			Gm_MQ0_38vs;
			Gm_0_MQ39;
	MA=9;
      }
      break;
    case 12:
      if(IF_H00eqMD0)
      {
	Gs_H00_39;
			Gm_AC00_39;
	MA=13;
      }
      else
      {
	Gs_o0_19;
	Gs_o20_41;
			Gm_MD00_19;
			Gm_H30_39;
	MA=14;
      }
      break;
    case 13:
      Gs_o0_19;
			Gm_MD00_19;
			Gm_H30_39;
      MA=14;
      break;
    case 14:
      if(IF_b && (!IF_MQ9))
      {
	Gs_MQ0_39;
			Gm_H00_39;
	MA=15;
      }
      else if(IF_b && IF_MQ9)
      {
	Gs_MQ10_39;
			Gm_H00_39;
	MA=15;
      }
      else
      {
	Gs_MQ0_39;
			Gm_H0_38vs;
			Gm_Linie0_H00;
	MA=20;
      }
      break;
    case 15:
      if(!IF_MQ9eqMQ10)
      {
	Gs_blind;
	MA=16;
      }
      else
      {
			Gm_MD10_19;
	MA=17;
      }
      break;
    case 16:
      Gs_H00_39;
			Gm_H1_39hs;
			Gm_MQ1_39hs;
			Gm_Linie00_H00_H0;
      MA=17;
      break;
    case 17:
      if(!IF_b)
      {
	Gs_H00_39;
	Gs_Mode4;
			Gm_AC00_39;
			Gm_step;
	MA=2;
      }
      else
      {
	Gs_H00_39;
			Gm_AC00_39;
	MA=18;
      }
      break;
    case 18:
      Gs_AD2;
			Gm_MD00_9;
			Gm_MQ0_19vs;
      MA=19;
      break;
    case 19:
      Gs_AD1;
      Gs_o10_19;
      Gs_Mode3;
			Gm_H00_9;
			Gm_H10_19;
			Gm_H20_39;
			Gm_saetTL_0bc;
			Gm_step;
      MA=13;
      break;
    case 20:
      Gs_AC00_39H40_41;
			Gm_MQ0_39;
			Gm_spild;
      MA=17;
      break;
    case 24:
      if(IF_H00eqMD0)
      {
	Gs_H00_39;
			Gm_AC00_39;
			Gm_MQ0_38vs;
			Gm_0_MQ39;
	MA=10;
      }
      else
      {
	Gs_H00_39;
	Gs_Addition;
			Gm_H1_39hs;
			Gm_Linie00_H00_H0;
			Gm_Linie39_MQ0;
			Gm_step;
	MA=8;
      }
      break;
    }
    break;
  case 15: /* NK */
    switch(MA)
    {
    case 1:
      if(!IF_ACeq0)
      {
	Gs_AC00_39H40_41;
			Gm_H00_39;
	MA=2;
      }
      else
      {
	Gs_AC00_39H40_41;
			Gm_H00_39;
	MA=14;
      }
      break;
    case 2:
      if(IF_H00eqH0)
      {
	Gs_o10_19;
			Gm_TD;
	MA=3;
      }
      else
      {
	Gs_o10_19;
			Gm_H10_19vs;
	MA=4;
      }
      break;
    case 3:
      if(IF_OR41)
      {
	Gs_Addition;
			Gm_MQ0_19;
	MA=6;
      }
      else
      {
	Gs_blind;
	MA=6;
      }
      break;
    case 4:
      Gs_H10_19;
			Gm_TD;
      MA=5;
      break;
    case 5:
      if(!IF_OR41)
      {
	Gs_AC00_39H40_41;
			Gm_H1_39hs;
			Gm_Linie00_H00_H0;
	MA=6;
      }
      else
      {
        Gs_AC00_39H40_41;
			Gm_H1_39hs;
			Gm_Linie00_H00_H0;
	MA=3;
      }
      break;
    case 6:
      if(IF_H0eqH1)
      {
	Gs_H00_39;
			Gm_H0_38vs;
			Gm_Linie0_H00;
			Gm_oH39;
			Gm_tael_i_TD;
	MA=6;
      }
      else
      {
	Gs_blind;
	MA=8;
      }
      break;
    case 8:
      if(!IF_OR41)
      {
	Gs_H00_39;
			Gm_AC00_39;
	MA=13;
      }
      else
      {
	Gs_AD1;
	Gs_o10_19;
			Gm_MD00_9;
			Gm_MD10_19;
			Gm_0_MQ0;
			Gm_tael_i_TD;
	MA=9;
      }
      break;
    case 9:
      if(IF_MQ10)
      {
	Gs_blind;
	MA=10;
      }
      else
      {
	Gs_H00_39;
			Gm_AC00_39;
	MA=11;
      }
      break;
    case 10:
      Gs_H00_39;
			Gm_H1_39hs;
			Gm_Linie00_H00_H0;
			Gm_MQ1_19hs;
			Gm_0_MQ0;
      MA=9;
      break;
    case 11:
      Gs_TD_skraa;
			Gm_H00_9;
      MA=12;
      break;
    case 12:
      Gs_o10_19;
      Gs_Mode3;
			Gm_TD;
			Gm_step;
      MA=6;
      break;
    case 13:
      if(!IF_M)
      {
	Gs_TD_skraa;
	Gs_Mode4;
			Gm_LI0_9;
			Gm_step;
			FL_laes10_41;
	MA=9;
      }
      else
      {
	Gs_TD_skraa;
	Gs_Mode4;
			Gm_LI0_9;
			Gm_IO;
			Gm_step;
			FL_laes10_39;
	MA=9;
      }
      break;
    case 14:
      if(!IF_OR41)
      {
	Gs_o10_19;
			Gm_TD;
	MA=13;
      }
      else
      {
	Gs_AD1;
	Gs_Mode4;
			Gm_MQ0_9;
			Gm_step;
	MA=2;
      }
      break;
    }
    break;
  case 16: /* NL */
    switch(MA)
    {
    case 1:
      if(!IF_ACeq0)
      {
	Gs_AC00_39H40_41;
			Gm_H00_39;
	MA=16;
      }
      else
      {
	Gs_AC00_39H40_41;
			Gm_H00_39;
	MA=15;
      }
      break;
    case 15:
      Gs_MQ0_39;
			Gm_AC00_39;
			Gm_step;
      MA=16;
      break;
    case 16:
      if(!IF_ACeq0)
      {
	Gs_o10_19;
			Gm_TD;
	MA=17;
      }
      else
      {
	Gs_o10_19;
			Gm_TD;
	MA=24;
      }
      break;
    case 17:
      if(!IF_H00eqH0)
      {
			Gm_MQ0_38vs;
			Gm_0_MQ39;
	MA=20;
      }
      else
      {
			Gm_MQ0_38vs;
			Gm_0_MQ39;
	MA=18;
      }
      break;
    case 18:
      if(IF_H0eqH1)
      {
	Gs_H00_39;
			Gm_H0_38vs;
			Gm_MQ0_H39;
			Gm_MQ0_38vs;
			Gm_0_MQ39;
			Gm_tael_i_TD;
	MA=18;
      }
      else
      {
	Gs_H00_39;
			Gm_AC00_39;
			Gm_MQ1_39hs;
			Gm_0_MQ0;
	MA=24;
      }
      break;
    case 20:
      Gs_H00_39;
			Gm_H1_39hs;
			Gm_Linie00_H00_H0;
			Gm_Linie39_MQ0;
			Gm_MQ1_39hs;
      MA=21;
      break;
    case 21:
      Gs_H00_39;
			Gm_AC00_39;
			Gm_MQ1_39hs;
			Gm_0_MQ0;
      MA=22;
      break;
    case 22:
      Gs_o10_19;
			Gm_H10_19vs;
      MA=23;
      break;
    case 23:
      Gs_H10_19;
			Gm_TD;
      MA=24;
      break;
    case 24:
      if(!IF_M)
      {
	Gs_TD_skraa;
	Gs_Mode4;
			Gm_LI0_9;
			Gm_step;
			FL_laes10_41;
	MA=9;
      }
      else
      {
	Gs_TD_skraa;
	Gs_Mode4;
			Gm_LI0_9;
			Gm_IO;
			Gm_step;
			FL_laes10_39;
	MA=9;
      }
      break;
    }
    break;
  case 17: /* HR */
  case 34: /* HK */
  case 50: /* HS */
  case 56: /* HV */
  case 60: /* HH */
    switch(MA)
    {
    case 1:
      if(IF_OR21 || IF_TL)
      {
        Gs_AD1;
	Gs_MD10_19;
			Gm_MD00_9;
			Gm_TD;
        MA=2;
      }
      else
      {
        Gs_blind;
	MA=19;
      }
      break;
    case 2:
      if(IF_OR22)
      {
        Gs_blind;
	MA=9;
      }
      else if(IF_OR24)
      {
        Gs_TD_skraa;
			Gm_AD1;
	MA=3;
      }
      else if(IF_OR25)
      {
        Gs_AD2;
			Gm_AD1;
	MA=5;
      }
      else
        PANIK("HR, step 2");
      break;
    case 3:
      if(IF_OR40)
      {
        Gs_TD_skraa;
			Gm_SR;
	MA=9;
      }
      else
      {
        Gs_SR;
			Gm_AD2;
			FL_laes0_920_41;
	MA=4;
      }
      break;
    case 4:
      Gs_AD2_skraa;
      			Gm_LI10_19;
			Gm_step;
			FL_skriv;
      MA=8;
      break;
    case 5:
      Gs_blind;
      			FL_laes0_41;
      MA=6;
      break;
    case 6:
      			Gm_step;
      MA=8;
      break;
    case 8:
      if(IF_OR25)
      {
        Gs_LI10_19;
			Gm_TD;
	MA=20;
      }
      else if(IF_OR24)
      {
        Gs_TD_skraa;
			Gm_SR;
	MA=9;
      }
      else
        PANIK("HR, step 8");
      break;
    case 9:
      /* MD39 set by UD */
      if(IF_MD39)
      {
        Gs_MD0_9;
			Gm_AD2;
	MA=11;
      }
      else
      {
        Gs_blind;
	MA=10;
      }
      break;
    case 10:
      if(!IF_OR23)
      {
        Gs_MD0_9;
	Gs_0h;
	Gs_Mode4;
			Gm_OT;
			Gm_step;
	MA=2;
      }
      else
      {
        Gs_MD0_9;
	Gs_1h;
	Gs_Mode4;
			Gm_OT;
			Gm_step;
	MA=2;
      }
      break;
    case 11:
      Gs_OT;
      Gs_o10_19;
      			Gm_H00_9;
			Gm_H10_19;
      MA=12;
      break;
    case 12:
      Gs_Addition;
      			Gm_MD00_9;
			Gm_step;
      MA=14;
      break;
    case 13:
      if(!IF_OR23)
      {
        Gs_0h;
	MA=15;
      }
      else
      {
        Gs_1h;
	MA=15;
      }
      break;
    case 14:
      if(!(IF_OR40 && IF_h))
      {
        Gs_Adder00_19;
			Gm_H00_9;
	MA=13;
      }
      else
      {
        Gs_blind;
	MA=13;
      }
      break;
    case 15:
      Gs_H00_9;
      			Gm_AD1;
      MA=16;
      break;
    case 16:
      Gs_AD2;
      			Gm_LI0_9;
			FL_laes10_41;
      MA=17;
      break;
    case 17:
      Gs_Adder00_19;
      Gs_Mode4;
      			Gm_OT;
			Gm_step;
      MA=2;
      break;
    case 19:
      Gs_Mode1;
      			Gm_step;
      MA=1;
      break;
    case 20:
      Gs_TD_skraa;
      			Gm_SR;
      MA=9;
      break;
    }
    break;
  case 18: /* TL */
  case 19: /* CK */
  case 20: /* CL */
    switch(MA)
    {
    case 1:
      Gs_AD1;
      Gs_Subtraktion;
      Gs_o10_19;
			Gm_AD2;
			Gm_H10_19;
      MA=2;
      break;
    case 2:
      Gs_AD2_skraa;
      Gs_o20_41;
			Gm_MD10_19;
			Gm_MD20_39;
      MA=3;
      break;
    case 3:
      if(!IF_MD10)
      {
	Gs_MD10_19;
	Gs_1c;
			Gm_TD;
	MA=13;
      }
      else
      {
	Gs_blind;
	Gs_1b;
	MA=4;
      }
      break;
    case 4:
      if(!IF_OR23)
      {
	Gs_Adder00_19;
			Gm_TD;
	MA=5;
      }
      else
      {
	Gs_Adder00_19;
			Gm_TD;
	MA=6;
      }
      break;
    case 5:
      if(!IF_OR25)
      {
	Gs_AC00_39H40_41;
			Gm_H00_39;
			Gm_MQ0_38vs;
			Gm_0_MQ39;
	MA=9;
      }
      else
      {
	Gs_AC00_39H40_41;
			Gm_H00_39;
	MA=10;
      }
      break;
    case 6:
      Gs_AC00_39H40_41;
			Gm_H00_39;
      MA=12;
      break;
    case 7:
      if(IF_TDeq0)
      {
	Gs_H00_39;
			Gm_AC00_39;
			Gm_0_MQ0;
	MA=21;
      }
      else if((!IF_TDeq0)&&IF_b)
      {
	Gs_H00_39;
			Gm_H1_39hs;
			Gm_Linie39_MQ0;
	MA=8;
      }
      else PANIK("TL, step 7");
      break;
    case 8:
			Gm_MQ39_H0;
			Gm_MQ1_39hs;
			Gm_tael_i_TD;
      MA=7;
      break;
    case 9:
      if(IF_TDeq0)
      {
	Gs_H00_39;
			Gm_AC00_39;
			Gm_0_MQ0;
			Gm_MQ1_39hs;
	MA=21;
      }
      else if((!IF_TDeq0)&&IF_b)
      {
	Gs_H00_39;
			Gm_H1_39hs;
			Gm_MQ1_39hs;
			Gm_Linie39_MQ0;
			Gm_Linie00_H00_H0;
			Gm_tael_i_TD;
	MA=9;
      }
      else PANIK("TL, step 9");
      break;
    case 10:
			Gm_oH00;
      MA=11;
      break;
    case 11:
      if(IF_TDeq0)
      {
	Gs_H00_39;
			Gm_AC00_39;
	MA=21;
      }
      else if((!IF_TDeq0)&&IF_b)
      {
	Gs_H00_39;
			Gm_H1_39hs;
			Gm_Linie39_H0;
			Gm_tael_i_TD;
	MA=11;
      }
      else PANIK("TL, step 11");
      break;
    case 12:
			Gm_oH00;
      MA=7;
      break;
    case 13:
      if(!IF_OR23)
      {
	Gs_AC00_39H40_41;
			Gm_H00_39;
	MA=14;
      }
      else
      {
	Gs_AC00_39H40_41;
			Gm_H00_39;
	MA=16;
      }
      break;
    case 14:
      if(!IF_OR25)
      {
			Gm_MQ0_38vs;
			Gm_0_MQ39;
	MA=15;
      }
      else
      {
			Gm_oH00;
	MA=19;
      }
      break;
    case 15:
      if(IF_TDeq0)
      {
	Gs_H00_39;
			Gm_AC00_39;
			Gm_MQ1_39hs;
			Gm_0_MQ0;
	MA=21;
      }
      else if((!IF_TDeq0)&&IF_c)
      {
	Gs_H00_39;
			Gm_H0_38vs;
			Gm_Linie0_H00;
			Gm_MQ0_H39;
			Gm_MQ0_38vs;
			Gm_tael_i_TD;
	MA=15;
      }
      else
        PANIK("TL/CK/CL step 15");
      break;
    case 16:
			Gm_oH00;
      MA=17;
      break;
    case 17:
      if(IF_TDeq0)
      {
	Gs_H00_39;
			Gm_AC00_39;
			Gm_0_MQ0;
	MA=21;
      }
      else if((!IF_TDeq0)&&IF_c)
      {
	Gs_H00_9;
			Gm_MQ0_38vs;
			Gm_Linie0_MQ39;
	MA=18;
      }
      else
        PANIK("TL/CK/CL step 17");
      break;
    case 18:
      Gs_H00_39;
			Gm_H0_38vs;
			Gm_MQ0_H39;
			Gm_tael_i_TD;
      MA=17;
      break;
    case 19:
      if(IF_TDeq0)
      {
	Gs_H00_39;
			Gm_AC00_39;
	MA=21;
      }
      else if((!IF_TDeq0)&&IF_c)
      {
	Gs_H00_39;
			Gm_H0_38vs;
			Gm_Linie0_H39;
			Gm_tael_i_TD;
	MA=19;
      }
      else
        PANIK("TL/CK/CL step 19");
      break;
    case 21:
      Gs_Mode4;
			Gm_saetTL_0bc;
			Gm_spild;
			Gm_step;
      MA=2;
      break;
    }
    break;
  case 21: /* GR */
    switch(MA)
    {
    case 1:
      if( (!IF_d) && IF_M )
      {
	Gs_MQ0_9;
	Gs_AC10_39H40_41;
			Gm_LI0_9;
			Gm_LI10_39;
			Gm_IO;
			FL_skriv;
	MA=21;
      }
      else if( (!IF_d) && (!IF_M) )
      {
	Gs_MQ0_9;
	Gs_AC10_39H40_41;
			Gm_LI0_9;
			Gm_LI10_39;
			FL_laes40_41;
	MA=21;
      }
      else
      {
	Gs_MQ0_9;
	Gs_AC10_19;
			Gm_LI0_9;
			Gm_LI10_19;
			FL_laes20_41;
	MA=21;
      }
      break;
    case 21:
      if(!IF_OR41)
      {
	Gs_AC00_9;
	Gs_Mode4;
			Gm_LI0_9;
			FL_skriv;
	MA=9;
      }
      else if( IF_OR41 && IF_ACstareq0 )
      {
	Gs_o0_9;
	Gs_Mode4;
			Gm_LI0_9;
			FL_skriv;
	MA=9;
      }
      else
      {
	Gs_Mode4;
	MA=9;
      }
      if(debug&DEBUGexecute)
      {
	fprintf(debug_fh, "GR[%d]: ",AD1);
	dumpword(debug_fh, LI);
	fprintf(debug_fh, "\n");
      }
      break;
    }
    break;
  case 22: /* GA */
    switch(MA)
    {
    case 1:
      if(OT==878 && LI==(943819424336ULL*4+2)) coredump();
      if(!IF_M)
      {
	Gs_AC00_9;
	Gs_Mode4;
			Gm_LI0_9;
			FL_laes10_41;
	MA=8;
      }
      else
      {
	Gs_AC00_9;
	Gs_Mode4;
			Gm_LI0_9;
			Gm_IO;
			FL_laes10_39;
	MA=8;
      }
      break;
    }
    break;
  case 23: /* GT */
    switch(MA)
    {
    case 1:
      if(!IF_M)
      {
	Gs_AC10_19;
	Gs_Mode4;
			Gm_LI10_19;
			FL_laes0_920_41;
	MA=8;
      }
      else
      {
	Gs_AC10_19;
	Gs_Mode4;
			Gm_LI10_19;
			Gm_IO;
			FL_laes0_920_39;
	MA=8;
      }
      break;
    }
    break;
  case 24: /* TK */
    switch(MA)
    {
    case 1:
      if(!IF_OR41)
      {
	Gs_AD1;
			Gm_MD00_9;
			Gm_MD10_39;
	MA=9;
      }
      else
      {
	Gs_AD1;
			Gm_MD00_9;
			Gm_MD10_39;
	MA=5;
      }
      break;
    case 5:
      Gs_MQ0_9;
      Gs_Addition;
			Gm_H00_9;
			Gm_H10_39;
			Gm_step;
      MA=7;
      break;
    case 7:
      Gs_Adder00_19;
			Gm_MD00_9;
      MA=9;
      break;
    case 9:
      if(!IF_MD0)
      {
	Gs_MD0_9;
	Gs_Addition;
			Gm_AD2;
	MA=10;
      }
      else
      {
	Gs_o0_19;
	Gs_Subtraktion;
			Gm_H00_39;
			Gm_step;
	MA=17;
      }
      break;
    case 10:
      Gs_AD2_skraa;
			Gm_TD;
      MA=11;
      break;
    case 11:
      Gs_AC00_39H40_41;
			Gm_H00_39;
      MA=14;
      break;
    case 14:
      if(!IF_TDeq0)
      {
	Gs_H00_39;
			Gm_H0_38vs;
			Gm_oH39;
			Gm_Linie0_H00;
			Gm_tael_i_TD;
	MA=14;
      }
      else
      {
	Gs_H00_39;
	Gs_Mode4;
			Gm_AC00_39;
			Gm_spild;
			Gm_step;
	MA=2;
      }
      break;
    case 17:
      Gs_Adder00_19;
			Gm_AD2;
      MA=18;
      break;
    case 18:
      Gs_AD2_skraa;
      Gs_Subtraktion;
			Gm_TD;
      MA=19;
      break;
    case 19:
      Gs_AC00_39H40_41;
			Gm_H00_39;
      MA=20;
      break;
    case 20:
      if(!IF_TDeq0)
      {
	Gs_H00_39;
			Gm_H1_39hs;
			Gm_Linie00_H00_H0;
			Gm_tael_i_TD;
	MA=20;
      }
      else
      {
			Gm_MD00_39;
			Gm_step;
	MA=23;
      }
      break;
    case 23:
      Gs_Adder00_39;
			Gm_H1_39hs;
			Gm_Linie00_H00_H0;
      MA=24;
      break;
    case 24:
      Gs_H00_39;
      Gs_Mode4;
			Gm_AC00_39;
			Gm_spild;
			Gm_step;
      MA=2;
      break;
    }
    break;
  case 25: /* CA */
  case 43: /* NC */
    switch(MA)
    {
    case 1:
      Gs_AC00_39H40_41;
      Gs_Subtraktion;
			Gm_H00_39;
      MA=6;
      break;
    case 6:
      Gs_AD1;
      Gs_o10_41;
			Gm_MD00_9;
			Gm_MD10_39;
			Gm_step;
      if(debug&DEBUGexecute)
      {
	int raddr,addr;
	raddr=(H&ONE0_9)>>SHIFT9;
	addr=AD1;
	fprintf(debug_fh, "CA/NC: %d ? %d\n",raddr,addr);
      }
      MA=15;
      break;
    case 8:
      if(!IF_OR24)
      {
	Gs_blind;
	MA=20;
      }
      else
      {
	Gs_blind;
	MA=21;
      }
      break;
    case 15:
      Gs_Adder00_19;
			Gm_AD2;
      MA=18;
      break;
    case 18:
      Gs_AD2;
      Gs_o10_41;
			Gm_AC00_9;
			Gm_AC10_39;
      MA=8;
      break;
    case 20:
      if(!IF_ACeq0)
      {
	Gs_blind;
	MA=22;
      }
      else
      {
	Gs_blind;
	MA=23;
      }
      break;
    case 21:
      if(!IF_ACeq0)
      {
	Gs_blind;
	MA=23;
      }
      else
      {
	Gs_blind;
	MA=22;
      }
      break;
    case 22:
      Gs_H00_39;
      Gs_0h;
      Gs_Mode4;
			Gm_AC00_39;
			Gm_step;
			Gm_tael_i_OT;
      MA=2;
      break;
    case 23:
      Gs_H00_39;
      Gs_Mode4;
			Gm_AC00_39;
      MA=2;
      break;
    }
    break;
  case 26: /* GM */
    switch(MA)
    {
    case 1:
      if((!IF_d)&&(!IF_M))
      {
	Gs_MQ0_39;
	Gs_Mode4;
			Gm_LI0_39;
			FL_laes40_41;
	MA=8;
      }
      else if((!IF_d)&&IF_M)
      {
	Gs_MQ0_39;
	Gs_Mode4;
			Gm_LI0_39;
			Gm_IO;
			FL_skriv;
	MA=8;
      }
      else
      {
	Gs_MQ0_19;
	Gs_Mode4;
			Gm_LI0_19;
			FL_laes20_41;
	MA=8;
      }
      if(debug&DEBUGexecute)
      {
	fprintf(debug_fh, "GM[%d]: ",AD1);
	dumpword(debug_fh, LI);
	fprintf(debug_fh, "\n");
      }
      break;
    }
    break;
  case 27: /* PM */
    switch(MA)
    {
    case 1:
      if(debug&(DEBUGexecute|DEBUGdrum))
      {
	int i;
	i=cnames[53].caddress;
	if(i != -1)
	{
	  if(OT==(i+5) && (LI&(ONE0_9|ONE20_41))==3925601879942ULL) segmentdump();
	}
      }
			FL_laes0_41;
      MA=2;
      break;
    case 2:
      Gs_blind;
			Gm_step;
      MA=4;
      break;
    case 4:
      if(!IF_d)
      {
	Gs_LI0_39;
	Gs_LI40_41;
			Gm_MQ0_39;
			Gm_H40_41;
	MA=5;
      }
      else
      {
	Gs_MD0_9;
	Gs_o10_41;
			Gm_MQ0_9;
			Gm_MQ10_39;
	MA=5;
      }
      break;
    case 5:
      Gs_MQ0_9;
      Gs_Mode4;
			Gm_H00_9;
			Gm_step;
      MA=2;
      break;
    }
    break;
  case 28: /* XR */
    switch(MA)
    {
    case 1:
      Gs_MQ0_39;
			Gm_H00_39;
      MA=2;
      break;
    case 2:
      Gs_AC00_39H40_41;
			Gm_MQ0_39;
      MA=3;
      break;
    case 3:
      Gs_H00_39;
      Gs_Mode4;
			Gm_AC00_39;
      MA=2;
      break;
    }
    break;
  case 29: /* GI */
    switch(MA)
    {
    case 1:
      if(!IF_M)
      {
	Gs_IN;
	Gs_Mode4;
			Gm_LI0_9;
			FL_laes10_41;
	MA=8;
      }
      else
      {
	Gs_IN;
	Gs_Mode4;
			Gm_LI0_9;
			Gm_IO;
			FL_laes10_39;
	MA=8;
      }
      break;
    }
    break;
  case 30: /* PS */
    switch(MA)
    {
    case 1:
      Gs_AD1;
      Gs_Mode4;
			Gm_SR;
      MA=2;
      break;
    }
    break;
  case 31: /* PP */
    switch(MA)
    {
    case 1:
      Gs_AD1;
      Gs_Mode4;
			Gm_AD0;
      MA=2;
      break;
    }
    break;
  case 32: /* PA */
    switch(MA)
    {
    case 1:
      Gs_TD_skraa;
      Gs_Mode4;
			Gm_LI0_9;
			FL_laes10_41;
      MA=8;
      break;
    }
    break;
  case 33: /* PT */
    switch(MA)
    {
    case 1:
      Gs_TD;
      Gs_Mode4;
			Gm_LI10_19;
			FL_laes0_920_41;
      MA=8;
      break;
    }
    break;
  case 35: /* PI */
  case 51: /* VY */
    switch(MA)
    {
    case 1:
      if(!IF_OR21)
      {
	Gs_IN;
	Gs_TD_skraa;
			Gm_H00_9;
			Gm_H10_19;
	MA=2;
      }
      else
      {
	Gs_BY0_9;
	Gs_TD_skraa;
			Gm_H00_9;
			Gm_H10_19;
	MA=2;
      }
      break;
    case 2:
      Gs_TD;
      Gs_o20_41;
      Gs_Subtraktion;
			Gm_MD10_19;
			Gm_MD20_39;
			Gm_step;
      MA=4;
      break;
    case 4:
      Gs_Adder00_19;
			Gm_TD;
      MA=5;
      break;
    case 5:
      Gs_AD1;
      Gs_TD_skraa;
      Gs_o10_19;
      Gs_Addition;
			Gm_MD00_9;
			Gm_MD10_19;
			Gm_step;
      MA=7;
      break;
    case 7:
      if(!IF_OR21)
      {
	Gs_Adder00_19;
	Gs_Mode4;
			Gm_IN;
	MA=2;
	if(debug&DEBUGindicator) print_indicator("PI");
      }
      else
      {
	Gs_Adder00_19;
	Gs_Mode4;
			Gm_BY0_9;
	MA=2;
      }
      break;
    }
    break;
  case 36: /* IS */
  case 37: /* IT */
  case 40: /* NS */
  case 41: /* NT */
    switch(MA)
    {
    case 1:
      if(IF_h)
      {
	Gs_AD1;
	Gs_MD10_19;
			Gm_MD00_9;
			Gm_TD;
	MA=18;
      }
      else
      {
	Gs_AD1;
	Gs_o10_19;
	Gs_Addition;
			Gm_MD00_9;
			Gm_H10_19;
			Gm_MD20_39;
			Gm_step;
	MA=5;
      }
      break;
    case 5:
      Gs_Adder00_19;
			Gm_TD;
      MA=18;
      break;
    case 6:
      Gs_TD_skraa;
      Gs_AD2_skraa;
      Gs_o20_41;
			Gm_AD1;
			Gm_H10_19;
			Gm_H20_39;
      MA=7;
      break;
    case 7:
      Gs_o20_41;
			Gm_OR30_39;
			FL_laes0_41;
      MA=8;
      break;
    case 8:
      if(IF_OR25)
      {
	Gs_SR;
	Gs_H10_19;
			Gm_AD2;
			Gm_TD;
	MA=9;
      }
      else
      {
	Gs_o10_19;
	Gs_Mode1;
			Gm_H10_19;
			Gm_step;
	MA=5;
      }
      break;
    case 9:
      if(!IF_h)
      {
	Gs_blind;
	MA=19;
      }
      else
      {
	Gs_blind;
	MA=20;
      }
      break;
    case 16:
      Gs_Adder00_19;
			Gm_AD2;
      if(debug&DEBUGexecute)
      {
	int addr;
	addr=AD2;
	fprintf(debug_fh, "IS/IT/NS/NT: %d\n",addr);
      }
      MA=17;
      break;
    case 17:
      Gs_TD;
      Gs_Addition;
			Gm_MD10_19;
      MA=6;
      break;
    case 18:
      if(IF_OR23)
      {
	Gs_o0_9;
	Gs_o10_41;
			Gm_H00_9;
			Gm_MD10_39;
			Gm_step;
	MA=16;
      }
      else
      {
	Gs_o0_9;
	Gs_o10_41;
	Gs_Subtraktion;
			Gm_H00_9;
			Gm_MD10_39;
			Gm_step;
	MA=16;
      }
      break;
    case 19:
      if(debug&DEBUGexecute)
      {
	double x;
	int exponent;
	fprintf(debug_fh, "\n   AC: ");
	printword((AC&~ONE40_41)|(H&ONE40_41));
	fprintf(debug_fh, "   MQ: ");
	printword(MQ);
	
	fprintf(debug_fh, "   RF: ");

	if( (AC&ONE10)==0 )
	{
	  x=((double)(AC&ONE10_39))/((double)ONE11);
	}
	else
	{
	  x=-(((double)((-AC)&ONE10_39))/((double)ONE11));
	}
	if( (MQ&ONE0)==0 )
	{
	  exponent = (int) ((MQ&ONE0_9)>>SHIFT9);
	}
	else
	{
	  exponent = ((int) ((MQ&ONE0_9)>>SHIFT9))-1024;
	}
	for(;exponent>0;exponent--) x = x*2.0;
	for(;exponent<0;exponent++) x = x*0.5;

	fprintf(debug_fh, "%.10lg\n",x);
	/* dprint("   RM",AC,MQ);  */
	fprintf(debug_fh, "   s: %d     p: %d     tk: %d   tg: %d   by: %d\n", SR, AD0, TK, TG, BY);
	print_indicator("Mode 1");
      }
      if( (debug&DEBUGexecute) || ((debug&DEBUGdrum) && (debug&DEBUGbuffer)))
      {
	time_t time1;
	fprintf(debug_fh, "Execute[%d%s]: ",OT,h?"h":"");
	dumpword(debug_fh, LI);
	time1 = time(NULL);
#ifdef WINDOWS
	fprintf(debug_fh, "   clock: %I64d %I64d %ld\n", clock_count, clock_count-last_execute_clock_count, time1-start_time);
#else
	fprintf(debug_fh, "   clock: %lld %lld %ld\n", clock_count, clock_count-last_execute_clock_count, time1-start_time);
#endif
	last_execute_clock_count=clock_count;
      }
      if(debug&DEBUGexecute)
      {
	if(h?(((LI<<10)&ONE20_25)>>SHIFT25==34):((LI&ONE20_25)>>SHIFT25==34))
	{
#ifdef WINDOWS
	  fprintf(debug_fh, "clock since last HK: %I64d\n", clock_count-last_clock_count_HK);
#else
	  fprintf(debug_fh, "clock since last HK: %lld\n", clock_count-last_clock_count_HK);
#endif
	  last_clock_count_HK=clock_count;
	}
	/* dptest(); */
	if((!h)&&(LI==(Opcode(Op_GT) | Address1(1) | r_relative | Right(Opcode(Op_PS) | Address1(1016) | Indirmark))))
	{
	  /* GT r1, PS (1016) */
	  coredump();
	}
      }
      if(!IF_LI40)
      {
	Gs_LI0_9;
	Gs_LI20_41;
	Gs_Mode1;
			Gm_H00_9;
			Gm_OR20_41;
			Gm_tael_i_OT;
			Gm_step;
	MA=8;
      }
      else
      {
	Gs_LI0_9;
	Gs_LI20_29;
	Gs_LI40_41;
	Gs_1h;
	Gs_Mode1;
			Gm_H00_9;
			Gm_OR20_29;
			Gm_OR40_41;
			Gm_step;
	MA=8;
      }
      break;
    case 20:
      if(!IF_LI40)
      {
	Gs_LI0_9;
	Gs_LI20_41;
	Gs_1h;
	Gs_Mode1;
			Gm_H00_9;
			Gm_OR20_41;
			Gm_tael_i_OT;
			Gm_step;
	MA=6;
      }
      else
      {
	Gs_LI10_19;
	Gs_LI30_39;
	Gs_Linie30_39_Linie_20_29;
	Gs_LI40_41;
	Gs_0h;
	Gs_Mode1;
			Gm_TD;
			Gm_OR20_29;
			Gm_OR40_41;
			Gm_tael_i_OT;
			Gm_step;
	MA=6;
      }
      break;
    }
    break;
  case 38: /* CM */
    switch(MA)
    {
    case 1:
      Gs_Subtraktion;
			FL_laes0_41;
      MA=3;
      break;
    case 3:
      Gs_AC00_39H40_41;
      Gs_MQ0_39;
			Gm_H00_39;
			Gm_step;
      MA=6;
      break;
    case 6:
      if(!IF_d)
      {
	Gs_LI0_39;
	Gs_MQ0_39;
	Gs_LI40_41;
			Gm_MD00_39;
			Gm_H40_41;
			Gm_step;
	MA=8;
      }
      else
      {
	Gs_MD0_9;
	Gs_MQ0_9;
	Gs_o10_41;
			Gm_MD00_9;
			Gm_MD10_39;
			Gm_step;
	MA=8;
      }
      break;
    case 8:
      Gs_Adder00_39;
			Gm_H0_38vs;
			Gm_oH39;
			Gm_Linie0_H00;
      MA=10;
      break;
    case 10:
      Gs_AC00_39;
			Gm_MD00_39;
      MA=15;
      break;
    case 15:
      Gs_H00_39;
			Gm_AC00_39;
			Gm_step;
      MA=23;
      break;
    case 17:
      Gs_MD00_39;
      Gs_Mode4;
			Gm_AC00_39;
			Gm_step;
      MA=2;
      break;
    case 22:
      Gs_MD00_39;
      Gs_0h;
      Gs_Mode4;
			Gm_AC00_39;
			Gm_tael_i_OT;
			Gm_step;
      MA=2;
      break;
    case 23:
      if(!IF_ACeq0)
      {
	Gs_blind;
	MA=17;
      }
      else
      {
	Gs_blind;
	MA=22;
      }
      break;
    }
    break;
  case 39: /* BT */
  case 49: /* BS */
    switch(MA)
    {
    case 1:
      Gs_AD1;
      Gs_Subtraktion;
			Gm_MD00_9;
      MA=21;
      break;
    case 21:
      Gs_TD_skraa;
      Gs_o10_19;
			Gm_H00_9;
			Gm_MD10_19;
			Gm_step;
      MA=23;
      break;
    case 23:
      Gs_Adder00_19;
			Gm_H00_9;
      MA=24;
      if(debug&DEBUGexecute)
      {
	int raddr,tael;
	raddr=AD1;
	tael=TD;
	if(raddr>511) raddr=raddr-1024;
	if(tael>511) tael=tael-1024;
	fprintf(debug_fh, "BS/BT: %d > %d? %s H00: %d\n",raddr,tael,((raddr>tael)?"OK":"SKIP"),((H&ONE00)?1:0));
      }
      break;
    case 24:
      if(IF_H00)
      {
	Gs_Mode4;
	MA=2;
      }
      else
      {
	Gs_0h;
	Gs_Mode4;
			Gm_step;
			Gm_tael_i_OT;
	MA=2;
      }
      break;
    }
    break;
  case 42: /* GP */
    switch(MA)
    {
    case 1:
      if(!IF_M)
      {
	Gs_OR0_9;
	Gs_Mode4;
			Gm_LI0_9;
			FL_laes10_41;
	MA=8;
      }
      else
      {
	Gs_OR0_9;
	Gs_Mode4;
			Gm_LI0_9;
			Gm_IO;
			FL_laes10_39;
	MA=8;
      }
      break;
    }
    break;
  case 44: /* IL */
  case 45: /* US */
    if(Buffer == NULL)
    {
      TO_error=1;
      GIER_stop();
      fprintf(debug_fh, "IL/US not implemented\n");
      break;
    }
    switch(MA)
    {
    case 1:
      if(debug&DEBUGbuffer)
      {
	/* disk: qq 0.0 + blocksize.9 + trackno.21 + zeroes.27 + bufferaddr.39 */
	fprintf(debug_fh, "%s %d: R = %d.9 %d.19 %d.21 %d.39\n", (IF_OR25)?"US":"IL",
	       AD1,
	       (int) ((AC & ONE0_9)>>SHIFT9),
	       (int) ((AC & ONE10_19)>>SHIFT19),
	       (int) ((AC & ONE10_21)>>SHIFT21),
	       (int) ((AC & ONE22_39)>>SHIFT39));
      }
      if(IF_YEeq0)
      {
        Gs_OT;
	Gs_AC20_41;
			Gm_AD2;
			Gm_MD20_41;
			Gm_step;
        bufferaddr = (MD&ONE28_39)>>SHIFT39;
        MA=3;
      }
      else if(IF_AD1pos1eq1)
      {
        		Gmj;
			Gm_step;
        MA=15;
      }
      else
      {
        Gs_AC00_39H40_41;
			Gm_MD0_41;
			Gmj;
			Gm_step;
	MA=2;
      }
      break;
    case 2:
      if(IF_optaget)
      {
        Gs_blind;
	MA=1;
      }
      else
      {
	bufferdevice=AD1&15;
	bufferstatus=(AD1&16)!=0;
        if(debug&DEBUGbuffer)
	{
	  fprintf(debug_fh, "Buffer command to unit %d.\n", bufferdevice);
	}
	if(bufferdevice>=1 && bufferdevice<=6)
	{
	  int tapecommand,tapecommand2;
          bufferaddr = (AC&ONE28_39)>>SHIFT39;
	  bufferlen = (AC&ONE8_19)>>SHIFT19;
	  tapecommand = AD1 & ~15;
	  tapecommand2 = AD1 & ~31;
	  if(debug&DEBUGbuffer)
	  {
#ifdef WINDOWS
	    fprintf(debug_fh, "%s command %I64d %d (%d) to tape unit %d, block length %d, buffer address: %d\n",
		    (IF_OR25)?"US":"IL",clock_count,tapecommand, tapecommand2, bufferdevice, bufferlen, bufferaddr);
#else
	    fprintf(debug_fh, "%s command %lld %d (%d) to tape unit %d, block length %d, buffer address: %d\n",
		    (IF_OR25)?"US":"IL",clock_count,tapecommand, tapecommand2, bufferdevice, bufferlen, bufferaddr);
#endif
	  }
	  if(IF_OR25)
	  {
	    /* US to tape */
	    if(tapecommand2 == 0 || tapecommand2 == 128 || tapecommand2 == 32 || tapecommand2 == 160)
	    {
	      /* write block */
	      if(debug&DEBUGbuffer) fprintf(debug_fh, "%sWrite %d word%s on tape.\n", (tapecommand2&32?"Skip 5\" tape and ":""), bufferlen, (bufferlen==1)?"":"s");
              append_block(bufferdevice, bufferlen, (tapecommand&16)?4:7, tapecommand2>=128?0:1, bufferaddr);
	    }
	    else if(tapecommand2 == 64 || tapecommand2 == 192 || tapecommand2 == 96 || tapecommand2 == 224)
	    {
	      if(tapecommand == 80)
	      {
	        /* Wait */
		if(debug&DEBUGbuffer) fprintf(debug_fh, "Wait tape.\n");
	      }
	      else
	      {
		/* Rewind */
		if(debug&DEBUGbuffer) fprintf(debug_fh, "Rewind tape.\n");
		first_block(bufferdevice);
		dump_tapes("After rewind");
	      }
	    }
	  }
	  else
	  {
	    /* IL from tape */
	    if(tapecommand2 == 0 || tapecommand2 == 128)
	    {
	      if(debug&DEBUGbuffer) fprintf(debug_fh, "Read %d word%s from tape.\n", bufferlen, (bufferlen==1)?"":"s");
              read_block(bufferdevice, bufferlen, tapecommand2>=128?0:1, bufferaddr);
	    }
	    else if(tapecommand2 == 224 || tapecommand2 == 160)
	    {
	      if(debug&DEBUGbuffer) fprintf(debug_fh, "Get tape status.\n");
	      Buffer[bufferaddr] = BTape_status[bufferdevice-1];
	      if(debug&DEBUGbuffer) checkbuffer(bufferaddr);
	      BTape_status[bufferdevice-1] = TAPE_HD|TAPE_WRITABLE;
	    }
	    else if(tapecommand2 == 32)
	    {
	      if(debug&DEBUGbuffer) fprintf(debug_fh, "Backspace 1 block.\n");
	      backward_block(bufferdevice);
	      dump_tapes("After backspace 1 block.");
	    }
	    else if(tapecommand2 == 64 || tapecommand2 == 192)
	    {
	      if(debug&DEBUGbuffer) fprintf(debug_fh, "Forward to filemark.\n");
	      forward_filemark(bufferdevice);
	      dump_tapes("After forward to filemark.");
	    }
	    else if(tapecommand2 == 96)
	    {
	      if(debug&DEBUGbuffer) fprintf(debug_fh, "Backward to filemark.\n");
	      backward_filemark(bufferdevice);
	      dump_tapes("After backward to filemark.");
	    }
	  }
	  if(debug&DEBUGbuffer) fflush(debug_fh);
	}
	else if(bufferdevice==7)
	{
	  int reel,block1,nblocks,blockno,i,j;
	  /* Carrousel */
	  reel = (AC&ONE0_5)>>SHIFT5;
	  block1 = (AC&ONE6_9)>>SHIFT9;
	  nblocks = (AC&ONE16_19)>>SHIFT19;
          bufferaddr = (AC&ONE28_39)>>SHIFT39;
	  if(bufferstatus)
	  {
	    if(IF_OR25)
	    {
	      /* us 23; ignored */
	    }
	    else
	    {
	      /* il 23; status */
	      Buffer[bufferaddr] = last_carrstatus?ONE0:0;
	      if(debug&DEBUGbuffer)
	      {
#ifdef WINDOWS
		fprintf(debug_fh, "Write Buffer[%d] = %I64u ",bufferaddr,Buffer[bufferaddr]>>2);
#else
		fprintf(debug_fh, "Write Buffer[%d] = %llu ",bufferaddr,Buffer[bufferaddr]>>2);
#endif
		printword(Buffer[bufferaddr]);
	      }
	    }
	  }
	  else
	  {
	    if(IF_OR25)
	    {
	      /* us 7 */
	      if(debug&DEBUGbuffer)
	      {
		fprintf(debug_fh, "Carrousel US: Reel: %d Block: %d Blocks: %d\n", reel, block1, nblocks);
	      }
	      last_carrstatus = 0;
	      for(j=0; j<nblocks; j++)
	      {
		blockno = block1+j;
		if(blockno<CARROUSELBLOCKS)
		{
		  if(BCarr[reel][blockno]==NULL)
		    BCarr[reel][blockno]=malloc(sizeof(GIERword)*CARROUSELWORDS);
		  for(i=0; i<CARROUSELWORDS; i++)
		  {
		    BCarr[reel][blockno][i] = Buffer[bufferaddr++];
		    if(bufferaddr==4096) bufferaddr=0;
		  }
		}
		else
		{
		  last_carrstatus = 1;
		}
	      }
	    }
	    else
	    {
	      /* il 7 */
	      if(debug&DEBUGbuffer)
	      {
		fprintf(debug_fh, "Carrousel IL: Reel: %d Block: %d Blocks: %d\n", reel, block1, nblocks);
	      }
	      last_carrstatus = 0;
	      for(j=0; j<nblocks; j++)
	      {
		blockno = block1+j;
		if(blockno < CARROUSELBLOCKS)
		  {
		  if(BCarr[reel][blockno]==NULL)
		  {
		    BCarr[reel][blockno]=malloc(sizeof(GIERword)*CARROUSELWORDS);
		    for(i=0; i<CARROUSELWORDS; i++) BCarr[reel][blockno][i] = 0;
		  }
		  for(i=0; i<CARROUSELWORDS; i++)
		  {
		    Buffer[bufferaddr] = BCarr[reel][blockno][i];
		    if(debug&DEBUGbuffer) checkbuffer(bufferaddr);
		    bufferaddr++;
		    if(bufferaddr==4096) bufferaddr=0;
		  }
		}
		else
		{
		  last_carrstatus = 1;
		}
	      }
	    }
	  }
	  if(debug&DEBUGbuffer) fflush(debug_fh);
	}
	else if(bufferdevice>=8 && bufferdevice<=15)
	{
	  /* bufferdisk */
	  bufferdisk=bufferdevice-8;
	  if(bufferdisk>=MAXBDISKS)
	  {
	    fprintf(stderr, "Reference to buffer disk unit %d, but this simulator is only configured for %d buffer disk(s).\n",
		bufferdevice, MAXBDISKS);
	  }
	  else if(!BDisk_present[bufferdisk])
	  {
	    fprintf(stderr, "Buffer disk unit %d not present.\n", bufferdevice);
	  }
	  else
	  {
	    /* qq 0.0 + blocksize.9 + trackno.21 + zeroes.27 + bufferaddr.39 */
            bufferaddr = (AC&ONE28_39)>>SHIFT39;
	    buffertrack = (AC&ONE10_21)>>SHIFT21;
	    bufferlen = (AC&ONE0_9)>>SHIFT9;
	    if(debug&DEBUGbuffer)
	    {
#ifdef WINDOWS
	      fprintf(debug_fh, "%s %scommand %I64d to disk unit %d, block length %d, buffer address: %d track: %d\n",
		    (IF_OR25)?"US":"IL",(bufferstatus?"status ":""),clock_count,bufferdevice, bufferlen, bufferaddr, buffertrack);
#else
	      fprintf(debug_fh, "%s %scommand %lld to disk unit %d, block length %d, buffer address: %d track: %d\n",
		    (IF_OR25)?"US":"IL",(bufferstatus?"status ":""),clock_count,bufferdevice, bufferlen, bufferaddr, buffertrack);
#endif
	    }
	    if(bufferlen>BDisk_tracksize[bufferdisk]) bufferlen=BDisk_tracksize[bufferdisk];
	    if(IF_OR25)
	    {
	      /* US */
	      if(buffertrack>=BDisk_size[bufferdisk])
	      {
		fprintf(stderr, "Write outside buffer disk %d: Track: %d, size: %d\n", bufferdisk, buffertrack, BDisk_size[bufferdisk]);
		if(debug&DEBUGbuffer)
		fprintf(debug_fh, "Write outside buffer disk %d: Track: %d, size: %d\n", bufferdisk, buffertrack, BDisk_size[bufferdisk]);
	      }
	      else
	      {
		for(i=0; i<bufferlen; i++)
		{
		  BDisk[bufferdisk][i+buffertrack*BDisk_tracksize[bufferdisk]] = Buffer[bufferaddr++];
		  if(bufferaddr==4096) bufferaddr=0;
		}
		last_bufferlen = bufferlen;
	      }
	    }
	    else
	    {
	      /* IL */
	      if(bufferstatus)
	      {
		Buffer[bufferaddr] = ((GIERword)last_bufferlen)<<SHIFT19;
		if(debug&DEBUGbuffer) checkbuffer(bufferaddr);
		if(debug&DEBUGbuffer)
		{
#ifdef WINDOWS
		  fprintf(debug_fh, "Write Buffer[%d] = %I64u ",bufferaddr,Buffer[bufferaddr]>>2);
#else
		  fprintf(debug_fh, "Write Buffer[%d] = %llu ",bufferaddr,Buffer[bufferaddr]>>2);
#endif
		  printword(Buffer[bufferaddr]);
		}
	      }
	      else
	      {
		if(buffertrack>=BDisk_size[bufferdisk])
		{
		  fprintf(stderr, "Read outside buffer disk %d: Track: %d, size: %d\n", bufferdisk, buffertrack, BDisk_size[bufferdisk]);
		  if(debug&DEBUGbuffer)
		  fprintf(debug_fh, "Read outside buffer disk %d: Track: %d, size: %d\n", bufferdisk, buffertrack, BDisk_size[bufferdisk]);
		}
		else
		{
		  for(i=0; i<bufferlen; i++)
		  {
		    Buffer[bufferaddr] = BDisk[bufferdisk][i+buffertrack*BDisk_tracksize[bufferdisk]];
		    if(debug&DEBUGbuffer) checkbuffer(bufferaddr);
		if(debug&DEBUGbuffer)
		{
#ifdef WINDOWS
		  fprintf(debug_fh, "Write Buffer[%d] = %I64u ",bufferaddr,Buffer[bufferaddr]>>2);
#else
		  fprintf(debug_fh, "Write Buffer[%d] = %llu ",bufferaddr,Buffer[bufferaddr]>>2);
#endif
		  printword(Buffer[bufferaddr]);
		}
		   bufferaddr++;
		    if(bufferaddr==4096) bufferaddr=0;
		  }
		  last_bufferlen = bufferlen;
		}
	      }
	    }
	  }
	  if(debug&DEBUGbuffer) fflush(debug_fh);
	}
	else
	{
	  fprintf(stderr, "Reference to unknown buffer device: %d\n", bufferdevice);
	}
        Gs_Mode4;
	Gs_1AOK;
			Gm_step;
	MA=2;
      }
      break;
    case 3:
      Gs_AC00_9;
      Gs_AC10_19;
      Gs_1AOK;
      			Gm_OT;
			Gm_TD;
			Gm_step;
      MA=6;
      break;
    case 6:
      if(IF_OR25)
      {
        Gs_AC00_39H40_41;
			Gm_H00_41;
	MA=7;
      }
      else
      {
        		Gm_step;
        MA=16;
      }
      break;
    case 7:
      if(IF_TDeq0)
      {
        		Gmj;
			Gm_step;
        MA=23;
      }
      else
      {
	Gs_OT;
      			Gm_AD1;
			Gm_step;
	MA=9;
      }
      break;
    case 9:
			Gm_tael_i_OT;
			Gm_tael_i_TD;
			Gm_step;
			FL_laes0_41;
      MA=10;
      break;
    case 10:
    			Gmj;
      MA=11;
      break;
    case 11:
      Gs_LI0_41;
      			Gm_AC00_39H40_41;
      MA=13;
      break;
    case 13:
      if(IF_Coeq0)
      {
        Gs_AC00_39H40_41;
	Gs_1CO;
			Gm_MD0_41;
	MA=7;
        if(debug&DEBUGbuffer)
	{
#ifdef WINDOWS
	  fprintf(debug_fh, "Write Buffer[%d] = %I64u ",bufferaddr,(MD>>2));
#else
	  fprintf(debug_fh, "Write Buffer[%d] = %llu ",bufferaddr,(MD>>2));
#endif
	  printword(MD);
	}
	Buffer[bufferaddr] = MD;
	if(debug&DEBUGbuffer) checkbuffer(bufferaddr);
	bufferaddr++;
	if(bufferaddr>=4096) bufferaddr=0;
      }
      else
      {
        Gs_blind;
	MA=14;
      }
      break;
    case 14:
      			Gmj;
			Gm_step;
      MA=13;
      break;
    case 15:
      if(!IF_optaget)
      {
        Gs_Mode4;
			Gm_step;
	MA=2;
      }
      else
      {
        Gs_Mode4;
	Gs_0h;
			Gm_tael_i_OT;
                        Gm_step;
	MA=2;
      }
      break;
    case 16:
      if(!IF_TDeq0)
      {
	Gs_1CO;
      			Gm_MD0_41;
			Gm_step;
	MA=17;
      }
      else
      {
        Gs_AD2;
	Gs_Mode4;
			Gm_OT;
			Gm_step;
	MA=2;
      }
      break;
    case 17:
      			Gm_step;
      MA=20;
      break;
    case 19:
      if(debug&DEBUGbuffer)
      {
#ifdef WINDOWS
	fprintf(debug_fh, "Read Buffer[%d] = %I64u  ",bufferaddr,(Buffer[bufferaddr]>>2));
#else
	fprintf(debug_fh, "Read Buffer[%d] = %llu  ",bufferaddr,(Buffer[bufferaddr]>>2));
#endif
	printword(Buffer[bufferaddr]);
      }
      MD = Buffer[bufferaddr++];
      if(bufferaddr>=4096) bufferaddr=0;
      Gs_MD0_41;
      			Gm_LI0_41;
			FL_skriv;
      MA=16;
      break;
    case 20:
      Gs_OT;
      			Gm_AD1;
			Gmj;
			Gm_step;
      MA=21;
      break;
    case 21:
      if(IF_Coeq0)
      {
			Gm_tael_i_OT;
			Gm_tael_i_TD;
			FL_skriv;
        MA=19;
      }
      else
      {
        Gs_blind;
	MA=22;
      }
      break;
    case 22:
      			Gmj;
			Gm_step;
      MA=21;
      break;
    case 23:
      if(IF_Coeq0)
      {
        Gs_H00_39;
			Gm_AC00_39;
	MA=16;
      }
      else
      {
        Gs_blind;
	MA=7;
      }
      break;
    }
    break;
  case 46: /* GG */
    if(Tromle_size<=960)
    {
      TO_error=1;
      GIER_stop();
      fprintf(debug_fh, "GG only works on disc machines.\n");
      break;
    }
    switch(MA)
    {
    case 1:
      if(!IF_M)
      {
	Gs_TG;
	Gs_Mode4;
			Gm_LI0_9;
			FL_laes10_41;
	MA=8;
      }
      else
      {
	Gs_TG;
	Gs_Mode4;
			Gm_LI0_9;
			Gm_IO;
			FL_laes10_39;
	MA=8;
      }
      break;
    }
    break;
  case 52: /* LK */
    switch(MA)
    {
    case 1:
			Gm_saetTL_0bc;
			Gm_step;
      MA=12;
      break;
    case 12:
      if(IF_TL)
      {
#ifdef WINDOWS
        if(debug&DEBUGdrum) fprintf(debug_fh, "LK\t%d\t%d\t%I64d\n", AD1, TK+(TG-960)*960, clock_count);
#else
        if(debug&DEBUGdrum) fprintf(debug_fh, "LK\t%d\t%d\t%lld\n", AD1, TK+(TG-960)*960, clock_count);
#endif
	Gs_AD1;
			Gm_TBA;
			Gm_start_tromle_LK;
			/* TR_laes; */
	drum_wait=0;
	MA=13;
      }
      else
      {
	Gs_blind;
	drum_wait=1;
	MA=1;
      }
      break;
    case 13:
      Gs_Mode4;
      MA=2;
      break;
    }
    break;
  case 53: /* SK */
    switch(MA)
    {
    case 1:
			Gm_saetTL_0bc;
			Gm_step;
      MA=12;
      break;
    case 12:
      if(IF_TL)
      {
#ifdef WINDOWS
        if(debug&DEBUGdrum) fprintf(debug_fh, "SK\t%d\t%d\t%I64d\n", AD1, TK+(TG-960)*960, clock_count);
#else
        if(debug&DEBUGdrum) fprintf(debug_fh, "SK\t%d\t%d\t%lld\n", AD1, TK+(TG-960)*960, clock_count);
#endif
	Gs_AD1;
			Gm_TBA;
			Gm_start_tromle_SK;
			/* TR_skriv; */
	drum_wait=0;
	MA=13;
      }
      else
      {
	Gs_blind;
	drum_wait=1;
	MA=1;
      }
      break;
    case 13:
      Gs_Mode4;
      MA=2;
    break;
    }
    break;
  case 54: /* GK */
    switch(MA)
    {
    case 1:
      if(!IF_M)
      {
	Gs_TK;
			Gm_AD2;
			FL_laes20_41;
	MA=3;
      }
      else
      {
	Gs_TK;
			Gm_AD2;
			Gm_IO;
			FL_laes20_39;
	MA=3;
      }
      break;
    case 3:
      Gs_BY0_9;
      Gs_AD2_skraa;
      Gs_Mode4;
			Gm_LI0_9;
			Gm_LI10_19;
			FL_skriv;
      MA=9;
      break;
    }
    break;
  case 55: /* VK */
    switch(MA)
    {
    case 1:
      if(!IF_TL)
      {
	if(debug&DEBUGdrum && drumstat)
	{
	  fprintf(debug_fh, "drum_cell_count: %d\n", drum_cell_count);
	}

	drumstat=0;
	Gs_blind;
	drum_wait=1;
	MA=12;
      }
      /* This is probably not done like this... */
      else
      {
	if(debug&DEBUGdrum && drumstat)
	{
	  fprintf(debug_fh, "drum_cell_count: Drum already idle.\n");
	}
	drumstat=1;
	if(IF_AD1ge960)
	{
	  if(Tromle_size>960)
	  {
	    if(debug&DEBUGdrum) fprintf(debug_fh, "VK: %d\n", AD1);
	    Gs_AD1;
	    Gs_Mode4;
	    drum_wait=0;
			    Gm_TG;
	    MA=2;
	  }
	  else
	  {
	    if(debug&DEBUGdrum && AD1>960) fprintf(debug_fh, "Ignoring select group on non-disc machine VK: %d\n", AD1);
	    Gs_Mode4;
	    drum_wait=0;
	    MA=2;
	  }
	}
	else
	{
	  if(debug&DEBUGdrum) fprintf(debug_fh, "VK: %d\n", AD1);
	  Gs_AD1;
	  Gs_Mode4;
	  drum_wait=0;
			  Gm_TK;
	  MA=2;
	}
      }
      break;
    case 12:
			Gm_saetTL_0bc;
			Gm_step;
      drum_wait=1;
      MA=1;
      break;
    }
    break;
  case 58: /* SY */
    switch(MA)
    {
    case 1:
      Gs_AD1;
      Gs_o10_14o19;
      Gs_Addition;
			Gm_AD2;
			Gm_H10_19hs;
			Gm_H20_29;
      MA=14;
      break;
    case 14:
      Gs_H10_29;
			Gm_AD1;
			Gm_H10_19vs;
      MA=15;
      break;
    case 15:
      Gs_o0_9;
      Gs_H10_29;
			Gm_H00_9;
			Gm_H10_19vs;
			FL_laes0_41;
      MA=16;
      break;
    case 16:
      Gs_H10_29;
			Gm_H10_19vs;
      MA=17;
      break;
    case 17:
      Gs_AD2_skraa;
      Gs_H10_19;
			Gm_H10_19;
      MA=19;
      break;
    case 19:
      Gs_LI0_19;
      Gs_o20_41;
			Gm_MD0_19;
			Gm_MD20_39;
      MA=21;
      break;
    case 21:
			Gmj;
			Gm_step;
      MA=22;
      break;
    case 22:
      if(!IF_jSY)
      {
	Gs_AD2;
			Gm_BS3_9;
	if((BY & (8+16+32+64))&selected_out[1]) printer_SY(BS);
	if((BY & (8+16+32+64))&selected_out[2]) {sound_sync(); typewriter_SY(BS); }
	if((BY & (8+16+32+64))&selected_out[3]) punch_SY(BS);
	if((BY & (8+16+32+64))&selected_out[4]) plotter_SY(BS);
	if(debug&DEBUGexecute)
	{
	  int c,c2,uppercase;
	  uppercase=0;
	  c = BS&127;
	  c2 = flx2a(c, &uppercase);
#ifdef WINDOWS
	  fprintf(debug_fh, "SY: %d (clock=%I64d): ",BS&127,clock_count);
#else
	  fprintf(debug_fh, "SY: %d (clock=%lld): ",BS&127,clock_count);
#endif
	  if(c == 0)
	    fprintf(debug_fh, "SPACE\n");
	  else if(c == 58)
	    fprintf(debug_fh, "LC\n");
	  else if(c == 60)
	    fprintf(debug_fh, "UC\n");
	  else if(c == 30)
	    fprintf(debug_fh, "TAB\n");
	  else if(c == 64)
	    fprintf(debug_fh, "CR\n");
	  else
	    fprintf(debug_fh, "%c\n",c2);
	}
        SY_count=0;
	MA=23;
      }
      else
      {
	Gs_blind;
	MA=21;
      }
      break;
    case 23:
      Gs_Adder00_19;
      Gs_1_Zs;
      Gs_Mode4;
			Gm_LI0_19;
			FL_laes20_41;
      MA=9;
      break;
    }
    break;
  case 59: /* LY */
    switch(MA)
    {
    case 1:
      if(IF_BY8&&(!IF_BY9))
      {
			Gm_1_Zl;
			Gm_step;
	MA=3;
      }
      else
      {
			Gmj;
			Gm_step;
	MA=16;
      }
      break;
    case 3:
			Gmj;
			Gm_step;
      MA=4;
      break;
    case 4:
      if(IF_jLY)
      {
	Gs_blind;
	MA=3;
      }
      else
      {
			Gm_MD00_41;
			Gm_step;
	MA=7;
      }
      break;
    case 7:
      Gs_MD00_41;
      Gs_Mode4;
			Gm_AC00_41;
      MA=2;
      break;
    case 16:
      if(IF_jLY)
      {
	Gs_blind;
	MA=1;
      }
      else
      {
	Gs_blind;
	MA=18;
      }
      break;
    case 18:
      if((IF_BY8&&(!IF_BY9))||((!IF_BY8)&&IF_BY9))
      {
	Gs_BT0_9;
			Gm_AC00_9;
			FL_laes10_41;
	MA=20;
      }
      else
      {
	Gs_BL02_9;
	Gs_o1;
			Gm_AC00_9;
			FL_laes10_41;
	if(reader_parity_error) GIER_stop();
	MA=20;
      }
      if( (debug&DEBUGexecute) || (debug&DEBUGdrum) )
      {
        static int uppercase=0;
	unsigned char c,c2;
	c = (AC&ONE0_9)>>SHIFT9;
        c2 = flx2a(c, &uppercase);
	fprintf(debug_fh, "LY: %d ",(int)((AC&ONE0_9)>>SHIFT9));
	if(c == 0)
	  fprintf(debug_fh, "SPACE");
	else if(c == 58)
	  fprintf(debug_fh, "LC");
	else if(c == 60)
	  fprintf(debug_fh, "UC");
	else if(c == 30)
	  fprintf(debug_fh, "TAB");
	else if(c == 64)
	  fprintf(debug_fh, "CR");
	else
	  fprintf(debug_fh, "%c",c2);
#ifdef WINDOWS
	fprintf(debug_fh, " clock: %I64d\n",clock_count);
#else
	fprintf(debug_fh, " clock: %lld\n",clock_count);
#endif
      }
      break;
    case 20:
      Gs_AC00_9;
      Gs_Mode4;
			Gm_LI0_9;
			Gm_1_Zl;
			Gm_step;
			FL_skriv;
      MA=9;
      break;
    }
    break;
  case 61: /* GS */
    switch(MA)
    {
    case 1:
      if(!IF_M)
      {
	Gs_SR;
	Gs_Mode4;
			Gm_LI0_9;
			FL_laes10_41;
	MA=8;
      }
      else
      {
	Gs_SR;
	Gs_Mode4;
			Gm_LI0_9;
			Gm_IO;
			FL_laes10_39;
	MA=8;
      }
      break;
    }
    break;
  case 57: /* Fake ZJ */
    /*
     	R0-9	command
	R10-19	parameter

	command	parameter
	0	set plotter
		R10-17	pen width
		R18-19	pen color
    */
    switch(MA)
    {
      case 1:
	Gs_AC00_9;
	Gs_AC10_19;
	 	zj_command = (BUS & ONE0_9)>>SHIFT9;
	 	zj_parameter = (BUS & ONE10_19)>>SHIFT19;
	switch(zj_command)
	{
	  case 0:
	    /* set plotter */
	    plotter_set_pen(zj_parameter&3, zj_parameter>>2);
	    break;
	  default:
	    break;
	}
	MA=2;
	break;
      case 2:
	Gs_Mode4;
	MA=2;
	break;
    }
  case 62: /* Fake ZL */
    switch(MA)
    {
      case 1:
	MA=2;
	if(debug&DEBUGexecute)
	{
	  if(AD1==313) coredump();
	}
	if(AD1==0)
	{
	  BUS &= FLYDENDE(((double) (clock_count-base_clock_count))/((double) gier_clock));
	  base_clock_count=clock_count;
			Gm_MQ0_9;
			Gm_AC10_39;
	}
	else if(AD1==1)
	{
	  time_t time1;
	  long time1ns;
	  struct timespec clock1;
	  double dtime1;
	  clock_gettime(CLOCK_REALTIME, &clock1);
	  time1 = clock1.tv_sec - start_clock.tv_sec;
	  time1ns = clock1.tv_nsec - start_clock.tv_nsec;
	  if(time1ns < 0)
	  {
	    time1--;
	    time1ns += 1000000000;
	  }
	  dtime1 = (double) time1;
	  dtime1 += ((double) time1ns)/1.0e9;

	  BUS &= FLYDENDE(dtime1);
	  start_clock.tv_sec = clock1.tv_sec;
	  start_clock.tv_nsec = clock1.tv_nsec;
			Gm_MQ0_9;
			Gm_AC10_39;
	}
	else if(AD1==2)
	{
	  /* Wait for OB=1 */
	  if(lastOB==IF_OB)
	  {
	    /* Loop */
	    MA=1;
	  }
	  else
	  {
	    lastOB=IF_OB;
	    Gs_Mode4;
	    MA=2;
	  }
	}
	else if(AD1==3)
	{
	  GIERword rnd;
	  /* use rdrand to generate random number */
	  if(rdrand(10,&rnd))
	  {
	    BUS &= rnd&ONE0_39;
	    Set00;
			  Gm_AC00_39;
	    Gs_Mode4;
	    MA=2;
	  }
	  else
	  {
	    printf("rdrand does not work.\n");
	  }
        }
#ifdef STRANGE
	else if(AD1==4)
	{
	  BUS &= use_strange?ONE0_39:(~ONE0_39);
	  use_strange = (AC&ONE0)!=0;
	  Set00;
			  Gm_AC00_39;
	  Gs_Mode4;
	  MA=2;
        }
#endif

	break;
      case 2:
	Gs_Mode4;
	Gs_o0_41;
			Gm_AC00_9;
			Gm_MQ10_39;
	MA=2;
	break;
    }
    break;
  case 63: /* UD */
    switch(MA)
    {
    case 1:
      if(IF_h)
      {
	Gs_AD2;
	Gs_o20_41;
	Gs_0h;
			Gm_H00_9;
			Gm_H20_39;
	MA=6;
      }
      else
      {
	Gs_OT;
	Gs_o10_19;
	Gs_1h;
			Gm_H00_9;
			Gm_H10_19;
	MA=21;
      }
      break;
    case 6:
      Gs_AD1;
			Gm_AD2;
      MA=17;
      break;
    case 17:
      Gs_o0_9;
      Gs_AD2_skraa;
			Gm_MD00_9;
			Gm_MD10_19;
			Gm_MD20_39;
			FL_laes0_41;
      MA=18;
      break;
    case 18:
      Gs_H00_9;
      Gs_o20_41;
      Gs_Mode1;
			Gm_AD2;
			Gm_OR30_39;
			Gm_IO;
			Gm_step;
      MA=5;
      break;
    case 21:
			Gm_MD00_9;
			Gm_step;
      MA=22;
      break;
    case 22:
      Gs_blind;
      MA=23;
      break;
    case 23:
      Gs_Adder00_19;
			Gm_OT;
      MA=24;
      break;
    case 24:
      Gs_AD2;
      Gs_o20_41;
			Gm_H00_9;
			Gm_H20_39;
      MA=6;
      break;
    }
    break;
  default: /* Unknown opcode */
    TO_error=1;
    GIER_stop();
    fprintf(stderr, "Unknown opcode: %d\n", (int)((OR&ONE20_25)>>SHIFT25));
    break;
  }
  after_MA();
}

void Mode3()
{
  /*
	Help stuff for mode 2.
  */
  microdump("Mode3:");
  switch(MA)
  {
  case 1:
    if(IF_ACeq0)
    {
      Gs_AD1;
      Gs_Subtraktion;
			Gm_H00_9;
			Gm_H10_39;
      MA=5;
    }
    else
    {
      Gs_AC00_39H40_41;
      Gs_1b;
      			Gm_MQ0_39;
      MA=2;
    }
    break;
  case 2:
    if(IF_MQ9eqMQ10)
    {
      Gs_AD1;
      Gs_o10_41;
      Gs_Addition;
      			Gm_H00_9;
			Gm_H10_39;
      MA=3;
    }
    else if(IF_b)
    {
      Gs_AD1;
      Gs_Addition;
      			Gm_H00_9;
			Gm_H10_39;
      MA=18;
    }
    else
      PANIK("Mode 3, step 2");
    break;
  case 3:
    if(IF_MQ9eqMQ11)
    {
      			Gm_MQ0_38vs;
			Gm_0_MQ39;
			Gm_tael_i_TD;
      MA=4;
    }
    else if(IF_b)
    {
      Gs_MQ0_39;
      			Gm_AC00_39;
      MA=5;
    }
    else
      PANIK("Mode 3, step 3");
    break;
  case 4:
    if(IF_MQ9eqMQ11)
    {
       			Gm_MQ0_38vs;
			Gm_0_MQ39;
			Gm_tael_i_TD;
      MA=3;
    }
    else if(IF_b)
    {
      Gs_MQ0_39;
      			Gm_AC00_39;
      MA=5;
    }
    else
      PANIK("Mode 3, step 4");
    break;
  case 5:
    Gs_TD_skraa;
    			Gm_MD00_9;
			Gm_MD10_39;
    MA=6;
    break;
  case 6:
    Gs_TD;
    Gs_o20_41;
    Gs_1b;
    			Gm_MQ10_19;
			Gm_MQ20_39;
    MA=7;
    break;
  case 7:
    if(IF_b)
    {
      Gs_Adder00_19;
      			Gm_H00_9;
    }
    else
      PANIK("Mode 3, step 7");
    MA=8;
    break;
  case 8:
    if(IF_H00eqH0)
    {
      Gs_H00_9;
      			Gm_MQ0_9;
      MA=12;
    }
    else
    {
      Gs_OT;
      			Gm_AC00_9;
      MA=9;
    }
    break;
  case 9:
    if(!IF_H00)
    {
      Gs_o0_9;
      Gs_Mode1;
      			Gm_OT;
			Gm_step;
      MA=1;
    }
    else
    {
      Gs_o0_41;
      			Gm_AC00_39;
      MA=10;
    }
    break;
  case 10:
    Gs_o0o2_19;
    			Gm_H0_19vs;
			Gm_oH00;
    MA=11;
    break;
  case 11:
    Gs_H00_9;
    			Gm_MQ0_9;
    MA=12;
    break;
  case 12:
    if(IF_b)
    {
      Gs_AC00_9;
      Gs_Mode4;
      			Gm_H00_9;
			Gm_step;
    }
    else
      PANIK("Mode 3, step 12");
    MA=2;
    break;
  case 13:
    Gm_1b;
    MA=15;
    break;
  case 15:
    if( (!IF_MQ9eqMQ10) && IF_b)
    {
      MA=6;
    }
    else if(IF_MQ9eqMQ10)
    {
      Gs_o0_41;
      			Gm_AC00_39;
      MA=6;
    }
    else
      PANIK("Mode 3, step 15");
    break;
  case 16:
    Gs_AC00_39H40_41;
			Gm_H00_39;
    MA=21;
    break;
  case 18:
    			Gm_MQ1_39hs;
    MA=4;
    break;
  case 20:
    MA=21;
    break;
  case 21:
    if(!IF_d)
    {
      Gs_LI0_39;
      Gs_LI40_41;
      Gs_Mode2;
    			Gm_MD00_39;
			Gm_H40_41;
			Gm_step;
      MA=24;
    }
    else
    {
      Gs_o10_41;
      Gs_Mode2;
      			Gm_MD10_39;
			Gm_step;
      MA=24;
    }
    break;
  }
  after_MA();
}

void Mode4()
{
  /*
	Last part of execution of the instruction
  */
  microdump("Mode4:");
  switch(MA)
  {
  case 2:
#ifdef STRANGE
    if(IF_OR41 && (((OR&ONE20_25)>>SHIFT25)==13))
    {
      /* DKF */
      DKFc = IMPROVE_DKF(DKFa,DKFb);
      if(use_strange)
      {
	AC=(AC&(~ONE10_39))|(DKFc&ONE10_39);
	MQ=(MQ&(~ONE0_9))|(DKFc&ONE0_9);
      }
    }
#endif
    if((IF_X)&&(!IF_V))
    {
      Gs_MQ0_39;
      			Gm_H00_39;
			Gm_IO;
      MA=3;
    }
    else if((IF_X)&&(IF_V))
    {
      Gs_MQ0_39;
      			Gm_H00_39;
			Gm_IO;
			Gm_tael_i_OT;
      MA=3;
    }
    else if((!IF_X)&&(!IF_V)&&(!IF_IK))
    {
      Gs_Mode1;
      			Gm_step;
			Gm_IO;
      MA=1;
    }
    else if((!IF_X)&&(IF_V)&&(!IF_IK))
    {
      Gs_Mode1;
      			Gm_step;
			Gm_tael_i_OT;
			Gm_IO;
      MA=1;
    }
    else if((!IF_X)&&(!IF_V)&&(IF_IK))
    {
      Gs_AD0;
      			Gm_AD2;
			Gm_IO;
      MA=6;
    }
    else if((!IF_X)&&(IF_V)&&(IF_IK))
    {
      Gs_AD0;
      			Gm_AD2;
			Gm_tael_i_OT;
			Gm_IO;
      MA=6;
    }
    break;
  case 3:
    Gs_AC00_39H40_41;
    			Gm_MQ0_39;
    MA=4;
    break;
  case 4:
    if(!IF_IK)
    {
      Gs_H00_39;
      Gs_Mode1;
      			Gm_AC00_39;
			Gm_step;
      MA=1;
    }
    else
    {
      Gs_H00_39;
      			Gm_AC00_39;
      MA=5;
    }
    break;
  case 5:
    Gs_AD0;
    			Gm_AD2;
    MA=6;
    break;
  case 6:
    Gs_IN;
    			Gm_AD0;
    MA=7;
    break;
  case 7:
    Gs_AD2;
    Gs_Mode1;
    			Gm_IN;
			Gm_step;
    MA=1;
    if(debug&DEBUGindicator) print_indicator("Mode 4");
    break;
  case 8:
    MA=9;
    break;
  case 9:
    MA=10;
    break;
  case 10:
    MA=2;
    break;
  }
  after_MA();
}

void Mode5()
{
  /* I don't have the microcode for the disc version of this, hence the "whatever" stuff */
  microdump("Mode5:");
  switch(MA)
  {
  case 1:
    if(debug&DEBUGexecute) fprintf(debug_fh, "Mode 5 started");
    Gs_OT;
    Gs_39_TDmode5;
    			Gm_MD00_9;
			Gm_step;
    MA=2;
    break;
  case 2:
    Gs_TK;
    Gs_tael_i_TD;
    			Gm_AD2;
    whatever=TG;
    MA=3;
    break;
  case 3:
    Gs_o0_9;
    			Gm_AD1;
			Gm_saetTL_0bc;
			Gm_step;
    MA=4;
    break;
  case 4:
    if(!IF_TL)
    {
      Gs_blind;
      MA=3;
    }
    else
    {
      Gs_TD_skraa;
      			Gm_TK;
			Gm_1b;
      TG=960;
      MA=5;
    }
    break;
  case 5:
    if(!IF_TDeq0)
    {
      Gs_tael_i_TD;
      MA=5;
    }
    else
    {
      Gs_o0_9;
			Gm_TBA;
			Gm_start_tromle_SK;
      			Gm_step;
      MA=6;
    }
    break;
  case 6:
    Gs_o0_9;
    Gs_39_TD;
    			Gm_OT;
			Gm_saetTL_0bc;
			Gm_step;
    MA=7;
    break;
  case 7:
    if(!IF_TL)
    {
      Gs_blind;
      MA=6;
    }
    else
    {
      Gs_o0_9;
      			Gm_TK;
      MA=9;
    }
    break;
  case 9:
    if(!IF_TDeq0)
    {
      Gs_tael_i_TD;
      MA=9;
    }
    else
    {
      Gs_o0_9;
			Gm_TBA;
			Gm_start_tromle_LK;
      			Gm_step;
      MA=10;
    }
    break;
  case 10:
    			Gm_saetTL_0bc;
                        Gm_step;
    MA=11;
    break;
  case 11:
    if(!IF_TL)
    {
      Gs_blind;
      MA=10;
    }
    else
    {
      Gs_AD2;
      			Gm_TK;
      TG=whatever;
      MA=12;
    }
    break;
  case 12:
    Gs_MD0_9;
    Gs_o10_41;
    			Gm_LI0_9;
			Gm_LI10_39;
			Gm_tael_i_OT;
			Gm_step;
			FL_laes40_41;
    MA=22;
    break;
  case 22:
    			Gm_step;
    MA=23;
    break;
  case 23:
    Gs_Mode1;
    			Gm_step;
    MA=1;
    if(debug&DEBUGexecute) fprintf(debug_fh, "Mode 5 finished");
    break;
  }
  after_MA();
}

void ModeTest1()
{
  microdump("ModeTest1:");
  switch(MA)
  {
  case 1:
    Gs_OT;
    			Gm_AD1;
    MA=2;
    break;
  case 2:
    Gs_AD1;
    			Gm_AD2;
    MA=3;
    break;
  case 3:
    Gs_AD2_skraa;
    Gs_AD2;
    			Gm_AC00_9;
			Gm_TD;
			Gm_tael_i_OT;
						FL_skriv;
    MA=4;
    break;
  case 4:
    Gs_TD_skraa;
    			Gm_IN;
    MA=5;
    if(debug&DEBUGindicator) print_indicator("Test1");
    break;
  case 5:
    Gs_TD;
    Gs_IN;
    			Gm_AC10_19;
			Gm_TA;
    MA=6;
    break;
  case 6:
    Gs_TA;
    			Gm_TK;
    MA=7;
    break;
  case 7:
    Gs_TK;
    			Gm_SR;
    MA=8;
    break;
  case 8:
    if(normal_stop_pressed)
    {
      GIER_stop();
      normal_stop_pressed=0;
      return;
    }
    else if(normal_singlestep_pressed)
    {
      normal_singlestep_pressed=0;
      normal_stop_pressed=1; /* stop next time */
    }
    Gs_SR;
    			Gm_H00_9;
    MA=1;
    break;
  }
  after_MA();
}

void ModeTest2()
{
  static GIERword TI=0;
  microdump("ModeTest2:");
  switch(MA)
  {
  case 1:
    Gs_OT;
    			Gm_AD1;
    MA=2;
    break;
  case 2:
    Gs_AC00_39H40_41;
    			Gm_LI0_39;
    MA=3;
    break;
  case 3:
    Gs_AC00_39H40_41;
    			Gm_H00_41;
			Gm_tael_i_OT;
						FL_laes0_41;
    MA=4;
    break;
  case 4:
    Gs_H00_39;
    Gs_Subtraktion;
    			TI=BUS;
    MA=5;
    break;
  case 5:
    BUS=TI;
    			Gm_AD0;
			Gm_TD;
			Gm_OR20_39;
    MA=6;
    break;
  case 6:
    Gs_LI0_39;
    Gs_Addition;
    			Gm_MD00_39;
    MA=7;
    break;
  case 7:
    Gs_TD;
    Gs_AD0;
    Gs_OR20_41;
    			Gm_MQ0_39;
    MA=8;
    break;
  case 8:
    if(normal_stop_pressed)
    {
      GIER_stop();
      normal_stop_pressed=0;
      return;
    }
    else if(normal_singlestep_pressed)
    {
      normal_singlestep_pressed=0;
      normal_stop_pressed=1; /* stop next time */
    }
    Gs_Adder00_39;
    			Gm_AC00_39;
    MA=1;
    break;
  }
  after_MA();
}

void ModeTest3()
{
  /*
  	Register	Control board name
	AC		R
	MQ		M
	MD		O
	H		H
	LI		L
	OR		F
	OT		r1
	SR		s1
	AD1		r2
	AD2		s2
	IN		in
	TA		ta
	TK		tk
	BL		bl
	BS		bs
	BY		by
  */
  microdump("ModeTest3:");
  switch(MA)
  {
  case 1:
    Gs_H00_39;
    			Gm_H1_39hs;
			Gm_Linie39_H0;
    MA=2;
    break;
  case 2:
    Gs_H00_39;
    			Gm_H1_39hs;
			Gm_Linie39_H0;
    MA=3;
    break;
  case 3:
    Gs_H00_39;
    			Gm_MQ0_39;
    MA=4;
    break;
  case 4:
    Gs_H00_39;
    			Gm_H0_38vs;
			Gm_oH39;
			Gm_MQ0_38vs;
			Gm_0_MQ39;
    MA=5;
    break;
  case 5:
    Gs_H00_39;
    			Gm_H0_38vs;
			Gm_oH39;
			Gm_MQ0_38vs;
			Gm_0_MQ39;
    MA=6;
    break;
  case 6:
    Gs_MQ0_39;
    Gs_Subtraktion;
    			Gm_MD00_39;
    MA=7;
    break;
  case 7:
    Gs_MD0_39;
    			Gm_LI0_39;
    MA=8;
    break;
  case 8:
    if(normal_stop_pressed)
    {
      GIER_stop();
      normal_stop_pressed=0;
      return;
    }
    else if(normal_singlestep_pressed)
    {
      normal_singlestep_pressed=0;
      normal_stop_pressed=1; /* stop next time */
    }
    Gs_Adder00_39;
    			Gm_AC00_39;
    MA=1;
    break;
  }
  after_MA();
}

void ModeTest4()
{
  microdump("ModeTest4:");
  switch(MA)
  {
  case 1:
    Gs_H00_39;
    			Gm_H0_38vs;
			Gm_Linie0_H39;
    MA=2;
    break;
  case 2:
    Gs_H00_39;
    			Gm_H0_38vs;
			Gm_Linie0_H39;
    MA=3;
    break;
  case 3:
    Gs_H00_39;
    			Gm_MQ0_39;
    MA=4;
    break;
  case 4:
    Gs_H00_39;
    			Gm_H1_39hs;
			Gm_Linie39_H0;
			Gm_MQ1_39hs;
			Gm_MQ39_MQ0;
    MA=5;
    break;
  case 5:
    Gs_H00_39;
    			Gm_H1_39hs;
			Gm_Linie39_H0;
			Gm_MQ1_39hs;
			Gm_MQ39_MQ0;
			Gm_tael_i_TD;
    MA=6;
    break;
  case 6:
    Gs_MQ0_39;
    Gs_Subtraktion;
    			Gm_MD0_39;
    MA=7;
    break;
  case 7:
    Gs_TD_skraa;
    			Gm_OT;
    MA=8;
    break;
  case 8:
    if(normal_stop_pressed)
    {
      GIER_stop();
      normal_stop_pressed=0;
      return;
    }
    else if(normal_singlestep_pressed)
    {
      normal_singlestep_pressed=0;
      normal_stop_pressed=1; /* stop next time */
    }
    Gs_Adder00_39;
    			Gm_AC00_39;
    MA=1;
    break;
  }
  after_MA();
}

void ModeTest5()
{
  microdump("ModeTest5:");
  switch(MA)
  {
  case 1:
    Gs_MD0_9;
    			Gm_IN;
    MA=2;
    if(debug&DEBUGindicator) print_indicator("Test 5A");
    break;
  case 2:
    Gs_MD30_39;
    Gs_Mode3;
    			Gm_OR30_39;
    MA=3;
    break;
  case 3:
    			Gm_IO;
    MA=4;
    break;
  case 4:
    Gs_AC00_9;
    Gs_Mode4;
    			Gm_IN;
    MA=5;
    if(debug&DEBUGindicator) print_indicator("Test 5B");
    break;
  case 5:
    Gs_AC00_39H40_41;
    			Gm_OR30_39;
    MA=6;
    break;
  case 6:
    Gs_Mode1;
    			Gm_IO;
    MA=7;
    break;
  case 7:
    MA=8;
    break;
  case 8:
    if(normal_stop_pressed)
    {
      GIER_stop();
      normal_stop_pressed=0;
      return;
    }
    else if(normal_singlestep_pressed)
    {
      normal_singlestep_pressed=0;
      normal_stop_pressed=1; /* stop next time */
    }
    Gs_Mode2;
    MA=1;
  }
  after_MA();
}

void init_microcode()
{
  int i;
  step_count=0;
  clock_count=0;
  base_clock_count=0;
  sound_count_0=0;
  sound_count_1=0;
  SY_count=0;
  for(i=0; i<MAXBDISKS; i++)
  {
    BDisk[i] = (GIERword *) NULL;
    BDisk_tracksize[i] = 0;
    BDisk_present[i] = 0;
    BDisk_size[i] = 0;
  }
}

static void start_drum_disk()
{
  if(Tromle_size>960)
  {
    int i;
    i=(TK+(TG-960)*960)/96;
    if(i!=disk_cylinder)
    {
      disk_status=1; /* seek */
      last_disk_count = disk_count;
    }
    else
    {
      disk_status=2; /* On-cylinder, wait for track */
    }
  }
  else
  {
    drum_running=1;
    drum_cell_count=0;
  }
}

int is_drum_running()
{
  /*
	If GIER is equipped with a disk instead of a drum the timings are done as follows:

	The disk rotates 2400 rpm

	It has 100 cylinders, 12 heads and each physical track has 8 40 cell drum tracks.

	There is a gap of 0.3 msec between each drum track.

	The seek time is specified as 85 msec, irrespective of the
	seek distance.

	Specifications:

	Seek time: 38250 clock cycles.
	One rotation: 11250 clock cycles.
        Gap: 135 clock cycles.
	Track RW: 1271.25 clock cycles.
	Cell RW: 31.775 clock cycles.

	To make it simple, we use:

	Cell RW: 32 clock cycles
	Track RW: 40*32 = 1280 clock cycles
        Gap: 135 clock cycles
        Rotation: 8*(1280+135)=11320 clock cycles
	Seek time: 38250 clock cycles

	Read/write starts at the beginning of the track.

	disk_status keeps track of the disk:

        0: Idle
	1: Seeking
	2: On-cylinder, wait for track
	3: Read/write
  */
  if(Tromle_size > 960)
  {
    /*
     Disk replacing the drum.

     The disk access consists of three parts:

     Seek
     Wait for track
     The actual IO
    */
    if(disk_status==0)
    {
      return 0;
    }
    else if(disk_status==1)
    {
      /* Seeking */
      if(disk_count-last_disk_count>=38250)
      {
	disk_cylinder=(TK+(TG-960)*960)/96;
	disk_status=2;
	if(debug&DEBUGdrum)
	{
#ifdef WINDOWS
	  fprintf(debug_fh, "Disk: Status: %d cylinder: %d track: %d since last: %I64u drum_running: %d\n", disk_status, disk_cylinder, TK+(TG-960)*960, disk_count-last_disk_count, drum_running);
#else
	  fprintf(debug_fh, "Disk: Status: %d cylinder: %d track: %d since last: %llu drum_running: %d\n", disk_status, disk_cylinder, TK+(TG-960)*960, disk_count-last_disk_count, drum_running);
#endif
	}
      }
      return 1;
    }
    else if(disk_status==2)
    {
      int i,j;
      /* Wait for track on cylinder */
      i=(disk_count%11320)/(1280+135);
      j=(disk_count%11320)%(1280+135);
      if(i==(TK%8)&&j<2)
      {
	disk_status=3;
	drum_address=-1;
	drum_running=1;
	drum_cell_count=0;
	drum_count=0;
	if(debug&DEBUGdrum)
	{
#ifdef WINDOWS
	  fprintf(debug_fh, "Disk: Status: %d cylinder: %d track: %d since last: %I64u drum_running: %d\n", disk_status, disk_cylinder, TK+(TG-960)*960, disk_count-last_disk_count, drum_running);
#else
	  fprintf(debug_fh, "Disk: Status: %d cylinder: %d track: %d since last: %llu drum_running: %d\n", disk_status, disk_cylinder, TK+(TG-960)*960, disk_count-last_disk_count, drum_running);
#endif
	}
      }
      return 1;
    }
    else
    {
      /* During RW */
      return 1;
    }
  }
  else
  {
    /* 1-3 drums */
    return drum_running;
  }
}

void wait_drum()
{
  while(drum_running)
  {
    drumsave_MA=MA;
    drumsave_Mode=Mode;
    drum_address++;
    if(drum_address>39) drum_address=0;
    if(drum_mode==0)
    {
      /* LK */
      BUS = ~0ULL;
      Gs_TR_Add;
    			Gm_TA;
			Gm_AD1_til_TA;
      BUS = ~0ULL;
      Gs_TI0_41;
    			Gm_LI0_41_drum;
			FL_skriv_drum;
      BUS = ~0ULL;
      drum_step();
      Gs_stop_B_puls;
    			Gm_skift_B_A;
			Gm_TA_til_AD1;
    }
    else
    {
      /* SK */
      BUS = ~0ULL;
      Gs_TR_Add;
    			Gm_TA;
			Gm_AD1_til_TA;
      BUS = ~0ULL;
                        FL_laes0_41_drum;
      BUS = ~0ULL;
      Gs_LI0_41_drum;
    			Gm_TI0_41;
      BUS = ~0ULL;
      drum_step();
      Gs_stop_B_puls;
    			Gm_skift_B_A;
			Gm_TA_til_AD1;
    }
  }
}

void GIER_single_step()
{
  BUSinit;
  drum_count++;
  disk_count++;
  is_drum_running();
  if(drum_count>=DRUM_CELL_INTERVAL)
  {
    drum_address++;
    if(drum_address>39) drum_address=0;
    if(drum_running)
    {
      drumsave_MA=MA;
      drumsave_Mode=Mode;
      MA=1;
      if(drum_mode==0)
      {
	Mode=ModeLK;
      }
      else
      {
	Mode=ModeSK;
      }
    }
    drum_count-=DRUM_CELL_INTERVAL;
  }
  lastMode = Mode;
  lastMA = MA;
  switch(testmode)
  {
    case 0:
      (*Mode)();
      break;
    case 1:
      ModeTest1();
      break;
    case 2:
      ModeTest2();
      break;
    case 3:
      ModeTest3();
      break;
    case 4:
      ModeTest4();
      break;
    case 5:
      ModeTest5();
      break;
  }
    
  if(debug&DEBUGmicrostep)
  {
    if(lastMode==Mode1)
      fprintf(debug_fh, "Mode1:");
    else if(lastMode==Mode2)
      fprintf(debug_fh, "Mode2:");
    else if(lastMode==Mode3)
      fprintf(debug_fh, "Mode3:");
    else if(lastMode==Mode4)
      fprintf(debug_fh, "Mode4:");
    else if(lastMode==Mode5)
      fprintf(debug_fh, "Mode5:");
    else if(lastMode==ModeLK)
      fprintf(debug_fh, "ModeLK:");
    else if(lastMode==ModeSK)
      fprintf(debug_fh, "ModeSK:");
    else
      fprintf(debug_fh, "Modexx:");
    fprintf(debug_fh, " MA=%02d ", lastMA);
    fprintf(debug_fh, " BUS: ");
    printwordbin(BUS,0);
#ifdef WINDOWS
    fprintf(debug_fh, "   clock: %I64d", clock_count);
#else
    fprintf(debug_fh, "   clock: %lld", clock_count);
#endif
    fprintf(debug_fh," r1(OT): %d", OT);
    fprintf(debug_fh," r2(AD1): %d", AD1);
    fprintf(debug_fh," s1(SR): %d", SR);
    fprintf(debug_fh," s2(AD2): %d", AD2);
    fprintf(debug_fh," TD: %d", TD);
    fprintf(debug_fh,"\n");
    fprintf(debug_fh, "\n   AC: ");
    printword((AC&~ONE40_41)|(H&ONE40_41));
    fprintf(debug_fh, "   MQ: ");
    printword(MQ);
    fprintf(debug_fh, "   H:  ");
    printword(H);
    fprintf(debug_fh, "   MD: ");
    printword(MD);
    fprintf(debug_fh, (adder_mode==0)?"  H+MD:":"  H-MD:");
    printword(Adder);
  }
  step_count++;
  clock_count++;
  SY_count++;
  nimbi_board_poll();
  if(sound_enabled)
  {
    if(IF_AC00)
      sound_count_1++;
    else
      sound_count_0++;

    if(step_count>=sound_update_interval)
    {
      while(step_count>=sound_update_interval)
      {
	sound_update(sound_count_1>sound_count_0);
	step_count -= sound_update_interval;
      }
      sound_count_0=0;
      sound_count_1=0;
    }
  }
  else
  {
    step_count = 0;
  }
}

void GIER_run()
{
  /*
  	Run at most INTERFACE_CHECK_INTERVAL
	clock cycles, or until running is false.

	We also stop on mikrotempi stop.
  */
  int count,count2;
  count=0;
  count2=0;
  do
  {
    GIER_single_step();
    if((count2++)>CONTROL_PANEL_UPDATE_INTERVAL)
    {
      kb12_update();
      count2=0;
    }
  }
  while(running && (count++)<((debug&(~(DEBUGstat|DEBUGtime)))?5000:interface_check_interval) && !mikrotempi_stop_pressed);
  nimbi_board_poll();
}
