/*
	Global declarations for GIER

	(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
*/

typedef unsigned long long GIERword;

/* Bitmasks and shifts */

#define ONE000   0x80000000000ULL
#define ONE00    0x40000000000ULL
#define ONE00_0  0x60000000000ULL
#define ONE00_9  0x7ff00000000ULL
#define ONE00_19 0x7ffffc00000ULL
#define ONE00_39 0x7fffffffffcULL
#define ONE00_41 0x7ffffffffffULL
#define ONE0     0x20000000000ULL
#define ONE0_2   0x38000000000ULL
#define ONE0_3   0x3c000000000ULL
#define ONE0_5   0x3f000000000ULL
#define ONE0_7   0x3fc00000000ULL
#define ONE0_8   0x3fe00000000ULL
#define ONE0_9   0x3ff00000000ULL
#define ONE0_18  0x3ffff800000ULL
#define ONE0_19  0x3ffffc00000ULL
#define ONE0_23  0x3fffffc0000ULL
#define ONE0_38  0x3fffffffff8ULL
#define ONE0_39  0x3fffffffffcULL
#define ONE0_41  0x3ffffffffffULL
#define ONE1     0x10000000000ULL
#define ONE1_9   0x1ff00000000ULL
#define ONE1_10  0x1ff80000000ULL
#define ONE1_19  0x1ffffc00000ULL
#define ONE1_20  0x1ffffe00000ULL
#define ONE1_39  0x1fffffffffcULL
#define ONE2     0x08000000000ULL
#define ONE2_9   0x0ff00000000ULL
#define ONE2_19  0x0ffffc00000ULL
#define ONE2_41  0x0ffffffffffULL
#define ONE3     0x04000000000ULL
#define ONE3_9   0x07f00000000ULL
#define ONE4     0x02000000000ULL
#define ONE4_9	 0x03f00000000ULL
#define ONE5     0x01000000000ULL
#define ONE6     0x00800000000ULL
#define ONE6_9   0x00f00000000ULL
#define ONE7     0x00400000000ULL
#define ONE8     0x00200000000ULL
#define ONE8_19  0x003ffc00000ULL
#define ONE8_23  0x003fffc0000ULL
#define ONE8_39  0x003fffffffcULL
#define ONE9     0x00100000000ULL
#define ONE9_18  0x001ff800000ULL
#define ONE10    0x00080000000ULL
#define ONE10_14 0x000f8000000ULL
#define ONE10_19 0x000ffc00000ULL
#define ONE10_21 0x000fff00000ULL
#define ONE10_29 0x000fffff000ULL
#define ONE10_38 0x000fffffff8ULL
#define ONE10_39 0x000fffffffcULL
#define ONE10_41 0x000ffffffffULL
#define ONE11    0x00040000000ULL
#define ONE11_20 0x0007fe00000ULL
#define ONE11_39 0x0007ffffffcULL
#define ONE13    0x00010000000ULL
#define ONE14    0x00008000000ULL
#define ONE14_19 0x0000fc00000ULL
#define ONE15    0x00004000000ULL
#define ONE16    0x00002000000ULL
#define ONE16_19 0x00003c00000ULL
#define ONE17    0x00001000000ULL
#define ONE18    0x00000800000ULL
#define ONE19    0x00000400000ULL
#define ONE20    0x00000200000ULL
#define ONE20_25 0x000003f0000ULL
#define ONE20_29 0x000003ff000ULL
#define ONE20_39 0x000003ffffcULL
#define ONE20_41 0x000003fffffULL
#define ONE21    0x00000100000ULL
#define ONE22    0x00000080000ULL
#define ONE23    0x00000040000ULL
#define ONE24    0x00000020000ULL
#define ONE24_27 0x0000003c000ULL
#define ONE24_39 0x0000003fffcULL
#define ONE25    0x00000010000ULL
#define ONE26    0x00000008000ULL
#define ONE27    0x00000004000ULL
#define ONE27_29 0x00000007000ULL
#define ONE28    0x00000002000ULL
#define ONE28_29 0x00000003000ULL
#define ONE28_32 0x00000003e00ULL
#define ONE28_39 0x00000003ffcULL
#define ONE29    0x00000001000ULL
#define ONE30    0x00000000800ULL
#define ONE30_35 0x00000000fc0ULL
#define ONE30_39 0x00000000ffcULL
#define ONE31    0x00000000400ULL
#define ONE32    0x00000000200ULL
#define ONE33    0x00000000100ULL
#define ONE33_34 0x00000000180ULL
#define ONE33_37 0x000000001f0ULL
#define ONE33_39 0x000000001fcULL
#define ONE34    0x00000000080ULL
#define ONE34_39 0x000000000fcULL
#define ONE35    0x00000000040ULL
#define ONE35_37 0x00000000070ULL
#define ONE36    0x00000000020ULL
#define ONE36_39 0x0000000003cULL
#define ONE37    0x00000000010ULL
#define ONE38    0x00000000008ULL
#define ONE38_39 0x0000000000cULL
#define ONE39    0x00000000004ULL
#define ONE40    0x00000000002ULL
#define ONE40_41 0x00000000003ULL
#define ONE41    0x00000000001ULL


#define ONEBYTE0_9 0x03ff
#define ONEBYTE1 0x0100
#define ONEBYTE8 0x0002
#define ONEBYTE9 0x0001

#define SHIFT41 0
#define SHIFT40 1
#define SHIFT39 2
#define SHIFT38 3
#define SHIFT37 4
#define SHIFT36 5
#define SHIFT35 6
#define SHIFT34 7
#define SHIFT33 8
#define SHIFT32 9
#define SHIFT31 10
#define SHIFT30 11
#define SHIFT29 12
#define SHIFT28 13
#define SHIFT27 14
#define SHIFT26 15
#define SHIFT25 16
#define SHIFT24 17
#define SHIFT23 18
#define SHIFT22 19
#define SHIFT21 20
#define SHIFT20 21
#define SHIFT19 22
#define SHIFT18 23
#define SHIFT17 24
#define SHIFT16 25
#define SHIFT15 26
#define SHIFT14 27
#define SHIFT13 28
#define SHIFT12 29
#define SHIFT11 30
#define SHIFT10 31
#define SHIFT9 32
#define SHIFT8 33
#define SHIFT7 34
#define SHIFT6 35
#define SHIFT5 36
#define SHIFT4 37
#define SHIFT3 38
#define SHIFT2 39
#define SHIFT1 40
#define SHIFT0 41
#define SHIFT00 42

/*
	Indicator stuff
*/

/* IND_oper */
#define IND_I 0
#define IND_M 1
#define IND_N 2
#define IND_L 3
/* IND_addr1 */
#define IND_none 0
#define IND_K 1
#define IND_Z 2
#define IND_O 3
#define IND_T 4
#define IND_P 5
#define IND_Q 6
#define IND_R 7
/* IND_addr2 */
#define IND_A 2
#define IND_B 1
#define IND_C 3

/* Opcodes */

#define Op_QQ 0
#define Op_ZQ 1
#define Op_AR 2
#define Op_SR 3
#define Op_AN 4
#define Op_SN 5
#define Op_AC 6
#define Op_SC 7

#define Op_MB 8
#define Op_AB 9
#define Op_MT 10
#define Op_MK 11
#define Op_ML 12
#define Op_DK 13
#define Op_DL 14
#define Op_NK 15

#define Op_NL 16
#define Op_HR 17
#define Op_TL 18
#define Op_CK 19
#define Op_CL 20
#define Op_GR 21
#define Op_GA 22
#define Op_GT 23

#define Op_TK 24
#define Op_CA 25
#define Op_GM 26
#define Op_PM 27
#define Op_XR 28
#define Op_GI 29
#define Op_PS 30
#define Op_PP 31

#define Op_PA 32
#define Op_PT 33
#define Op_HK 34
#define Op_PI 35
#define Op_IS 36
#define Op_IT 37
#define Op_CM 38
#define Op_BT 39

#define Op_NS 40
#define Op_NT 41
#define Op_GP 42
#define Op_NC 43
#define Op_IL 44
#define Op_US 45
#define Op_GG 46
#define Op_GC 47

#define Op_PC 48
#define Op_BS 49
#define Op_HS 50
#define Op_VY 51
#define Op_LK 52
#define Op_SK 53
#define Op_GK 54
#define Op_VK 55

#define Op_HV 56
#define Op_ZJ 57
#define Op_SY 58
#define Op_LY 59
#define Op_HH 60
#define Op_GS 61
#define Op_ZL 62
#define Op_UD 63

#define Address1(x) ( (((GIERword)(x))&1023)<<SHIFT9 )
#define Address2(x) ( (((GIERword)(x))&1023)<<SHIFT19 )
#define Opcode(x) ( ((GIERword)(x))<<SHIFT25 )
#define Smark ( ONE26 )
#define Indirmark ( ONE27 )
#define r_relative ( ONE28 )
#define s_relative ( ONE29 )
#define p_relative ( ONE28|ONE29 )
#define Xmark ( ONE30 )
#define Vmark ( ONE31 )
#define Dmark ( ONE32 )
#define Ind_oper(x) ( ((GIERword)(x))<<SHIFT34 )
#define Ind_addr1(x) ( ((GIERword)(x))<<SHIFT37 )
#define Ind_addr2(x) ( ((GIERword)(x))<<SHIFT39 )
#define Halfword ( ONE40 )
#define Fmark ( ONE41 )
#define Right(x) ( ((GIERword)(x))>>10 | Halfword )

/*
	Debug flags:
*/

#define DEBUGmemory	1
#define DEBUGmicrostep	2
#define DEBUGmaskintal	4
#define DEBUGflydende	8
#define DEBUGBUS	16
#define DEBUGregisters	32
#define DEBUGindicator	64
#define DEBUGinterface	128
#define DEBUGdrum	256
#define DEBUGsound	512
#define DEBUGbuffer	1024
#define DEBUGexecute	2048
#define DEBUGtext	4096
#define DEBUGstat	8192
#define DEBUGtime	16384
#define DEBUGdrumrace	32768

/*
	Interface stuff
*/

/* No. of cycles between each interface check: */
#define INTERFACE_CHECK_INTERVAL 4500
/* No. of cycles between each reading of the lamp status: */
#define CONTROL_PANEL_UPDATE_INTERVAL 1901
#define MAX_COUNT 4499
#define COUNT_DELTA 100
/* Number of clock cycles per drum cell:

   Clock speed 459.5 KHz
   Drum rotate 50 Hz, 20 ms per rotation
   40-41 cells are transferred, because the transfer
   cannot start until a start of a cell is encountered.

   459500/50/40 = 229.75 clock cycles/cell

   Test program 8: 216 <= DRUM_CELL_INTERVAL <= 224

   On a GIER with a disk replacing the drum, the timing is different.
*/
  
#define DRUM_CELL_INTERVAL ((Tromle_size>960)?32:drum_clock)

/* Tape stuff */

#define READER_TAPE_WINDOW 16
#define READER_TAPE_OFFSET 16
#define PUNCH_TAPE_WINDOW 32
#define TYPEWRITER_TABLE_SIZE 4
#define PRINTER_WINDOW 32
#define PLOTTER_WINDOW 40

#ifndef TRUE
#define TRUE (1)
#endif
#ifndef FALSE
#define FALSE (0)
#endif
#ifndef True
#define True (1)
#endif
#ifndef False
#define False (0)
#endif

/* Buffer disks */

#define MAXBDISKS 2
#define MAXBDISKTYPES 10

typedef struct
{
  char *name;
  int tracksize;
  int size;
} bdisktype;

/* Buffer tapes */

#define MAXBTAPES 6

#define TAPE_PARITY ONE0
#define TAPE_FILEMARK ONE1
#define TAPE_LOADPOINT ONE2
#define TAPE_EOT ONE3
#define TAPE_WRITABLE ONE4
#define TAPE_HD ONE5

typedef struct 
{
  int len;
  int wordlen; /* 4 or 7 bytes per word */
  int parity;
  GIERword *block;
} btapeblock;

/* Buffer carrousel */

#define CARROUSELDEVICE 7
#define CARROUSELREELS 64
#define CARROUSELBLOCKS 16
#define CARROUSELWORDS 512
