summaryrefslogtreecommitdiff
path: root/miniemu/opcodes.h
blob: 37d092229f6f77f323281c2971cf5a31835550e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#pragma once

/*
 * Follows the general 8-bit opcodes:
 *
 * See http://www.c-jump.com/CIS77/CPU/IsaDesign/lecture.html
 *
 * iiirrmmm (general two operand opcode format)
 * 
 * iii instruction/opcode group
 * rr  register operand
 * mmm second operand
 *
 * iii  = 000 special commands (zero or one operand)
 *      = 001 or
 *      = 010 and
 *      = 011 cmp
 *      = 100 sub
 *      = 101 add
 *      = 11x mov
 *      = 110 mov (load)
 *      = 111 mov (store)
 *
 * rr  = 00 AX
 *       01 BX
 *       10 CX
 *       11 DX
 *
 * mmm = 000 AX
 *       001 BX
 *       010 CX
 *       011 DX
 *       100 illegal
 *       101 illegal
 *       110 direct memory
 *       111 constant
 *
 * 000iimmm (general one operand opcode format)
 * 
 * ii instruction/opcode group
 * mmm operand
 *
 * ii   = 00 (special commands) zero-operand commands
 *      = 01 jump instructions
 *      = 10 not
 *      = 11 stack (push and pop registers to/from stack)
 *
 * for jmp:
 *
 * mmm = 000 je (Z set)
 *       001 jne (Z not set)
 *       010 jb (C set)
 *       011 jbe (C set or Z set)
 *       100 ja (C not set and Z not set)
 *       101 jae (C not set)
 *       110 jmp (unconditional)
 *       111 jsr (subroutine call, push PC on stack)
 *
 * for not:
 *
 * mmm = 000 AX
 *       001 BX
 *       010 CX
 *       011 DX
 *       100 illegal
 *       101 illegal
 *       110 illegal
 *       111 illegal
 * 
 * for push/pop
 * 
 * mmm = 000 push AX
 *       001 push BX
 *       010 push CX
 *       011 push DX
 *       100 pop AX
 *       101 pop BX
 *       110 pop CX
 *       111 pop DX
 *
 * 00000iii zero-operand instructions
 * 
 * iii instruction/opcode group
 * 
 * iii = 000 illegal
 *     = 001 nop
 *     = 010 hlt
 *     = 011 ret (return from subroute call, restore PC from stack)
 *     = 100 illegal
 *     = 101 illegal
 *     = 110 illegal
 *     = 111 illegal
 *
 */
typedef enum Opcode {
	OPCODE_GROUP_ZERO_OPERANDS = (unsigned char)0x07,
	OPCODE_GROUP_ONE_OPERAND = (unsigned char)0x18,
	OPCODE_GROUP_TWO_OPERANDS = (unsigned char)0xe0,

	OPCODE_MOV_MASK = (unsigned char)0xc0,
	OPCODE_MOV_LD = (unsigned char)0xc0,
	OPCODE_MOV_ST = (unsigned char)0xe8,

	OPCODE_DST_MASK = (unsigned char)0x18,
	OPCODE_DST_AX_REG = (unsigned char)0x00,
	OPCODE_DST_BX_REG = (unsigned char)0x08,
	OPCODE_DST_CX_REG = (unsigned char)0x10,
	OPCODE_DST_DX_REG = (unsigned char)0x18,

	OPCODE_SRC_MASK = (unsigned char)0x07,
	OPCODE_SRC_AX_REG = (unsigned char)0x00,
	OPCODE_SRC_BX_REG = (unsigned char)0x01,
	OPCODE_SRC_CX_REG = (unsigned char)0x02,
	OPCODE_SRC_DX_REG = (unsigned char)0x03,
	OPCODE_SRC_CONST = (unsigned char)0x07,
	OPCODE_SRC_MEMORY = (unsigned char)0x06,

	OPCODE_OR = (unsigned char)0x20,
	OPCODE_AND = (unsigned char)0x40,
	OPCODE_CMP = (unsigned char)0x60,
	OPCODE_SUB = (unsigned char)0x80,
	OPCODE_ADD = (unsigned char)0xa0,

	OPCODE_JMP = (unsigned char)0x08,
	
	OPCODE_JMP_MASK = (unsigned char)0x07,
	OPCODE_JMP_JE = (unsigned char)0x00,
	OPCODE_JMP_JNE = (unsigned char)0x01,
	OPCODE_JMP_JB = (unsigned char)0x02,
	OPCODE_JMP_JBE = (unsigned char)0x03,
	OPCODE_JMP_JA = (unsigned char)0x04,
	OPCODE_JMP_JAE = (unsigned char)0x05,
	OPCODE_JMP_JMP = (unsigned char)0x06,
	OPCODE_JMP_JSR = (unsigned char)0x07,
	
	OPCODE_NOT = (unsigned char)0x10,
	
	OPCODE_STACK = (unsigned char)0x18,
	OPCODE_STACK_OPERAND_MASK = (unsigned char)0x3,
	OPCODE_STACK_PUSH = (unsigned char)0x0,
	OPCODE_STACK_POP = (unsigned char)0x4,

	OPCODE_ZERO_OPS_MASK = (unsigned char)0xf8,

	OPCODE_NOP = (unsigned char)0x01,
	OPCODE_HLT = (unsigned char)0x02,
	OPCODE_RET = (unsigned char)0x03
} Opcode;