1 /**
2  * DCPU-16 cpu constants and some generic functions
3  *
4  * See_Also:
5  *  http://pastebin.com/raw.php?i=Q4JvQvnM
6  */
7 module dcpu.microcode;
8 
9 /// Valid basic OpCodes
10 enum OpCode: ubyte {
11   ExtOpCode=0x00,   /// Switch to special OpCodes
12   SET,              /// SETs b to a
13   ADD,              /// b = b + a
14   SUB,              /// b = b - a
15   MUL,              /// b = b * a
16   MLI,              /// b = b * a with sign
17   DIV,              /// b = b / a
18   DVI,              /// b = b / a with sign
19   MOD,              /// b = b % a
20   MDI,              /// b = b % a with sign
21   AND,              /// b = b & a
22   BOR,              /// b = b | a
23   XOR,              /// b = b ^ a
24   SHR,              /// b = b >>> a (logical shift)
25   ASR,              /// b = b >> a (arithmetic shift)
26   SHL,              /// b = b << a
27   IFB,              /// Next instrucction if ( b & a ) != 0
28   IFC,              /// Next instrucction if ( b & a ) == 0
29   IFE,              /// Next instrucction if b == a
30   IFN,              /// Next instrucction if b != a
31   IFG,              /// Next instrucction if b > a
32   IFA,              /// Next instrucction if b > a signed
33   IFL,              /// Next instrucction if b < a
34   IFU,              /// Next instrucction if b < a signed
35   ADX=0x1a,         /// b = b + a + EX
36   SBX=0x1b,         /// b = b - a + EX
37   STI=0x1e,         /// sets b = a ; I++ ; J++
38   STD=0x1f          /// sets b = a ; I-- ; J---
39 }
40 
41 /// Valid ExtendedOpCode
42 enum ExtOpCode : ubyte {
43   JSR=0x01,   /// Pushes the addres of the next isntruction to the stack, then sets PC to a
44   HCF=0x07,   /// Fire in the hole!
45   INT=0x08,   /// Trigger a software interrupt with message A
46   IAG,        /// sets a = IA
47   IAS,        /// sets IA = a
48   RFI,        /// Return From Interrupt
49   IAQ=0x0c,   /// Queueing of interrupts if a != 0
50   HWN=0x10,   /// Sets a to number of devices
51   HWQ=0x11,   /// Retrive information about hardware device a
52   HWI=0x12    /// Sends an interrupt to hrdware a
53 }
54 
55 /// Operand type/value
56 enum Operand : ubyte {
57   /** General Registers */
58   A = 0x00,
59   B = 0x01,
60   C = 0x02,
61   X = 0x03,
62   Y = 0x04,
63   Z = 0x05,
64   I = 0x06,
65   J = 0x07,
66   /** [register] */
67   Aptr = 0x08,
68   Bptr = 0x09,
69   Cptr = 0x0A,
70   Xptr = 0x0B,
71   Yptr = 0x0C,
72   Zptr = 0x0D,
73   Iptr = 0x0E,
74   Jptr = 0x0F,
75   /** [register + next word] */
76   Aptr_word = 0x10,
77   Bptr_word = 0x11,
78   Cptr_word = 0x12,
79   Xptr_word = 0x13,
80   Yptr_word = 0x14,
81   Zptr_word = 0x15,
82   Iptr_word = 0x16,
83   Jptr_word = 0x17,
84   /** Stack */
85   POP_PUSH = 0x18,  /// PUSH if is 'b' operator. POP if is a 'a' operator
86   PEEK     = 0x19,  /// [SP]
87   PICK_word= 0x1a,  /// [SP + next word]
88   /** Not general registers */
89   SP = 0x1b,         /// Stack Pointer value
90   PC = 0x1c,        /// Program Counter value
91   EX = 0x1d,        /// Excess register value
92   NWord_ptr = 0x1e, /// [next word]
93   NWord = 0x1f,     /// next_word literal
94   Literal = 0x20    /// literal from -1 to 30 (only if is 'a' operator)
95 }
96 
97 /**
98  * Extract a particular information from a instruction
99  * Params:
100  *  what = Type of data to decode from a instruction
101            ("OpCode", "ExtOpCode","OpA" or "OpB")
102  *  word = Data to decode. A word and his two next words
103  * Returns: Extracted data from a instruction
104 */
105 ubyte decode(string what)(ushort word) pure {
106   // Format is aaaaaabbbbbooooo or aaaaaaooooo00000
107   static if (what == "OpCode") {
108     return word & 0b00000000_00011111;
109   } else if (what == "OpB" || what == "ExtOpCode") {
110     return (word >> 5) & 0b00000000_00011111;
111   } else if (what == "OpA") {
112     return (word >> 10) & 0b00000000_00111111;
113   }
114 }