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

Subversion Repositories tv80

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

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

powered by: WebSVN 2.1.0

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