OpenCores
URL https://opencores.org/ocsvn/tv80/tv80/trunk

Subversion Repositories tv80

[/] [tv80/] [trunk/] [sc_env/] [z80_decoder.cpp] - Blame information for rev 97

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 96 ghutchis
#include "z80_decoder.h"
2
 
3
char *table_r[] = { "B", "C", "D", "E", "H", "L", "(HL)", "A" };
4
char *table_cc[] = { "NZ", "Z", "NC", "C", "PO", "PE", "P", "M" };
5
char *table_rp[] = {"BC", "DE", "HL", "SP" };
6
char *table_rp2[] = {"BC","DE","HL","AF"};
7
char *table_alu[] = {"ADD A,","ADC A,","SUB","SBC A,","AND","XOR","OR","CP"};
8 97 ghutchis
char *table_im[] = {"0","0/1", "1", "2", "0", "0/1", "1", "2" };
9 96 ghutchis
 
10
void z80_decoder::op_print ()
11
{
12
        printf ("DECODE :[%04x] %s\n", op_addr, op_name);
13
}
14
 
15
void z80_decoder::decode_unpre()
16
{
17
        int x = opcode.range(7,6);
18
        int y = opcode.range(5,3);
19
        int z = opcode.range(2,0);
20
 
21
        sprintf (op_buf, "Unknown (%02x)", (int) opcode);
22
        op_name = op_buf;
23
 
24
        switch (x) {
25
                case 0 :
26
                        switch (z) {
27
                                case 0 :
28
                                        if (y == 0)
29
                                                op_name = "NOP";
30
                                        else if (y == 1)
31
                                                op_name = "EX AF, AF'";
32
                                        else if (y == 2) {
33
                                                op_name = "DJNZ %d";
34
                                                state = DISP;
35
                                        } else if (y == 3) {
36
                                                op_name = "JR %d";
37
                                                state = DISP;
38
                                        } else {
39
                                                sprintf (op_buf, "JR %s, %%02x", table_cc[y-4]);
40
                                                op_name = op_buf;
41
                                                state = IMM1;
42
                                        }
43
                                        break;
44
                                case 1 :
45
                                        if (opcode.bit(3)) {
46
                                                sprintf (op_buf, "ADD HL, %s", table_rp[y>>1]);
47
                                                op_name = op_buf;
48
                                        } else {
49
                                                sprintf (op_buf, "LD %s, %%04x", table_rp[y>>1]);
50
                                                op_name = op_buf;
51
                                                state = IMM2;
52
                                        }
53
                                        break;
54
                                case 2 :
55
                                        switch (y) {
56
                                                case 0 : op_name = "LD (BC), A"; break;
57
                                                case 1 : op_name = "LD (DE), A"; break;
58
                                                case 2 : op_name = "LD (%04x), HL"; state = IMM2; break;
59
                                                case 3 : op_name = "LD (%04x), A"; state = IMM2; break;
60
                                                case 4 : op_name = "LD A, (BC)"; break;
61
                                                case 5 : op_name = "LD A, (DE)"; break;
62
                                                case 6 : op_name = "LD HL, (%04x)"; state = IMM2; break;
63
                                                case 7 : op_name = "LD A, (%02x)"; state = IMM1; break;
64
                                        }
65
                                        break;
66
                                case 3 :
67
                                        if (opcode.bit(3)) {
68
                                                sprintf (op_buf, "DEC %s", table_rp[opcode.range(5,4)]);
69
                                                op_name = op_buf;
70
                                        } else {
71
                                                sprintf (op_buf, "INC %s", table_rp[opcode.range(5,4)]);
72
                                                op_name = op_buf;
73
                                        }
74
                                        break;
75
                                case 4 :
76
                                        sprintf (op_buf, "INC %s", table_r[y]);
77
                                        op_name = op_buf;
78
                                        break;
79
                                case 5 :
80
                                        sprintf (op_buf, "DEC %s", table_r[y]);
81
                                        op_name = op_buf;
82
                                        break;
83
                                case 6 :
84
                                        sprintf (op_buf, "LD %s, %%02x", table_r[y]);
85
                                        op_name = op_buf;
86
                                        state = IMM1;
87
                                        break;
88
                                case 7 :
89
                                        switch (y) {
90
                                                case 0 : op_name = "RLCA"; break;
91
                                                case 1 : op_name = "RRCA"; break;
92
                                                case 2 : op_name = "RLA"; break;
93
                                                case 3 : op_name = "RRA"; break;
94
                                                case 4 : op_name = "DAA"; break;
95
                                                case 5 : op_name = "CPL"; break;
96
                                                case 6 : op_name = "SCF"; break;
97
                                                case 7 : op_name = "CCF"; break;
98
                                        }
99
                                        break;
100
                        }
101
                break;
102
 
103
                case 1 :
104
                if ((z == 6) && (y == 6)) {
105
                        op_name = "HALT";
106
                } else {
107
                        sprintf (op_buf, "LD %s, %s", table_r[y], table_r[z]);
108
                        op_name = op_buf;
109
                }
110
                break;
111
 
112
                case 2 : // ALU
113
                        sprintf (op_buf, "%s %s", table_alu[y], table_r[z]);
114
                        op_name = op_buf;
115
                break;
116
 
117
                case 3 :
118
                        switch (z) {
119
                                case 0 :
120
                                        sprintf (op_buf, "RET %s", table_cc[y]);
121
                                        op_name = op_buf;
122
                                        break;
123
                                case 1 : // TBD, POP & opcodes
124
                                        switch (y) {
125
                                                case 0 : case 1: case 2 : case 3 :
126
                                                sprintf (op_buf, "POP %s", table_rp2[y>>1]);
127
                                                op_name = op_buf;
128
                                                break;
129
                                                case 4 : op_name = "RET"; break;
130
                                                case 5 : op_name = "EXX"; break;
131
                                                case 6 : op_name = "JP HL"; break;
132
                                                case 7 : op_name = "LD SP, HL"; break;
133
                                        }
134
                                        break;
135
                                case 2 :
136
                                        sprintf (op_buf, "JP %s, %%04x", table_cc[y]);
137
                                        op_name = op_buf;
138
                                        state = IMM2;
139
                                        break;
140
                                case 3 : // JP and opcodes
141
                                        switch (y) {
142
                                                case 0 : op_name = "JP %04x"; state = IMM2; break;
143
                                                case 1 : state = PRE_CB; break;
144
                                                case 2 : op_name = "OUT (%02x), A"; state = IMM1; break;
145
                                                case 3 : op_name = "IN A, (%02x)"; state = IMM1; break;
146
                                                case 4 : op_name = "EX (SP), HL"; break;
147
                                                case 5 : op_name = "EX DE, HL"; break;
148
                                                case 6 : op_name = "DI"; break;
149
                                                case 7 : op_name = "EI"; break;
150
 
151
                                        }
152
                                        break;
153
                                case 4 :
154
                                        sprintf (op_buf, "CALL %s, %%04x", table_cc[y]);
155
                                        op_name = op_buf;
156
                                        state = IMM2;
157
                                        break;
158
                                case 5 :
159
                                        switch (y) {
160
                                                case 0 :
161
                                                case 1 :
162
                                                case 2 :
163
                                                case 3 :
164
                                                        sprintf (op_buf, "PUSH %s", table_rp2[y>>1]);
165
                                                        op_name = op_buf;
166
                                                        break;
167
                                                case 4 :
168
                                                        op_name = "CALL %04x";
169
                                                        state = IMM2;
170 97 ghutchis
                                                        op_print();
171 96 ghutchis
                                                        break;
172
                                                case 5 : state = PRE_DD; break;
173
                                                case 6 : state = PRE_ED; break;
174
                                                case 7 : state = PRE_FD; break;
175
                                        }
176
                                        break;
177 97 ghutchis
                                case 6 :
178
                                        sprintf (op_buf, "IM %s", table_im[y]);
179
                                        op_name = op_buf;
180
                                        break;
181
                                break;
182
                                case 7 :
183
                                        switch (y) {
184
                                                case 0 : op_name="LD I,A"; break;
185
                                                case 1 : op_name="LD R,A"; break;
186
                                                case 2 : op_name="LD A,I"; break;
187
                                                case 3 : op_name="LD A,R"; break;
188
                                                case 4 : op_name="RRD"; break;
189
                                                case 5 : op_name="RLD"; break;
190
                                                case 6 : op_name="NOP"; break;
191
                                                case 7 : op_name="NOP"; break;
192
                                        }
193
                                break;
194 96 ghutchis
                        }
195
                break;
196
        }
197
        /*FOR x=0
198
z=0
199
        y=0     NOP     y=2     DJNZ d
200
        y=1     EX AF, AF'      y=3     JR d
201
                        y=4..7  JR cc[y-4], d
202
        Relative jumps and assorted ops
203
z=1
204
q=0             LD rp[p], nn
205
q=1             ADD HL, rp[p]
206
        16-bit load immediate/add
207
z=2
208
q=0     p=0     LD (BC), A      p=2     LD (nn), HL
209
        p=1     LD (DE), A      p=3     LD (nn), A
210
q=1     p=0     LD A, (BC)      p=2     LD HL, (nn)
211
        p=1     LD A, (DE)      p=3     LD A, (nn)
212
        Indirect loading
213
z=3
214
q=0             INC rp[p]
215
q=1             DEC rp[p]
216
        16-bit INC/DEC
217
z=4
218
                INC r[y]
219
        8-bit INC
220
z=5
221
                DEC r[y]
222
        8-bit DEC
223
z=6
224
                LD r[y], n
225
        8-bit load immediate
226
z=7
227
        y=0     RLCA    y=4     DAA
228
        y=1     RRCA    y=5     CPL
229
        y=2     RLA     y=6     SCF
230
        y=3     RRA     y=7     CCF
231
        Assorted operations on accumulator/flags
232
        */
233
 
234
        if (state == UNPRE) {
235
                //printf ("DECODE : %02x %s\n", (int) opcode, op_name);
236
                op_print();
237
        }
238
}
239
 
240
void z80_decoder::event()
241
{
242
        if ((en_decode == false) || !reset_n) return;
243
 
244
        if (!m1_n && !mreq_n && !rd_n && wait_n) {
245
                imm = 0;
246
                op_addr = (int) addr;
247
                switch ( (int) di.read() ) {
248
                        case 0xCB : state = PRE_CB; break;
249
                        case 0xDD : state = PRE_DD; break;
250
                        case 0xED : state = PRE_ED; break;
251
                        case 0xFD : state = PRE_FD; break;
252
                        default :
253
                        opcode = di;
254
                        state = UNPRE;
255
                        decode_unpre();
256
                        break;
257
                }
258
        } else if (!mreq_n && !rd_n && wait_n && (state != UNPRE)) {
259
                switch (state) {
260
                        case IMM2 :
261
                                imm = ((unsigned int) di) & 0xff;
262
                                state = IMM2B;
263
                                break;
264
                        case IMM2B :
265
                                imm |= ((unsigned int) di << 8)& 0xFF00;
266
                                sprintf (op_buf, op_name, imm);
267
                                op_name = op_buf;
268
                                op_print();
269
                                break;
270
                        case IMM1 :
271
                                imm = ((unsigned int) di) & 0xff;
272
                                sprintf (op_buf, op_name, imm);
273
                                op_name = op_buf;
274
                                op_print();
275
                                break;
276
                }
277
        }
278
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.