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

Subversion Repositories tv80

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /tv80/trunk/sc_env
    from Rev 95 to Rev 96
    Reverse comparison

Rev 95 → Rev 96

/sc_env_top.cpp
5,6 → 5,7
#include "Vtv80s.h"
#include "SpTraceVcd.h"
#include <unistd.h>
#include "z80_decoder.h"
 
extern char *optarg;
extern int optind, opterr, optopt;
17,8 → 18,9
char *dumpfile_name;
char *mem_src_name;
SpTraceFile *tfp;
z80_decoder dec0 ("dec0");
while ( (index = getopt(argc, argv, "d:i:")) != -1) {
while ( (index = getopt(argc, argv, "d:i:k")) != -1) {
printf ("DEBUG: getopt optind=%d index=%d char=%c\n", optind, index, (char) index);
if (index == 'd') {
dumpfile_name = new char(strlen(optarg)+1);
29,6 → 31,9
mem_src_name = new char(strlen(optarg)+1);
strcpy (mem_src_name, optarg);
memfile = true;
} else if (index == 'k') {
printf ("Z80 Instruction decode enabled\n");
dec0.en_decode = true;
}
}
sc_clock clk("clk125", 8, SC_NS, 0.5);
98,6 → 103,15
tv_resp0.di_resp (di_resp);
tv_resp0.dout (dout);
tv_resp0.halt_n (halt_n);
dec0.clk (clk);
dec0.m1_n (m1_n);
dec0.addr (addr);
dec0.mreq_n (mreq_n);
dec0.rd_n (rd_n);
dec0.wait_n (wait_n);
dec0.di (di);
dec0.reset_n (reset_n);
 
// create dumpfile
/*
/z80_decoder.cpp
0,0 → 1,260
#include "z80_decoder.h"
 
char *table_r[] = { "B", "C", "D", "E", "H", "L", "(HL)", "A" };
char *table_cc[] = { "NZ", "Z", "NC", "C", "PO", "PE", "P", "M" };
char *table_rp[] = {"BC", "DE", "HL", "SP" };
char *table_rp2[] = {"BC","DE","HL","AF"};
char *table_alu[] = {"ADD A,","ADC A,","SUB","SBC A,","AND","XOR","OR","CP"};
 
void z80_decoder::op_print ()
{
printf ("DECODE :[%04x] %s\n", op_addr, op_name);
}
 
void z80_decoder::decode_unpre()
{
int x = opcode.range(7,6);
int y = opcode.range(5,3);
int z = opcode.range(2,0);
sprintf (op_buf, "Unknown (%02x)", (int) opcode);
op_name = op_buf;
switch (x) {
case 0 :
switch (z) {
case 0 :
if (y == 0)
op_name = "NOP";
else if (y == 1)
op_name = "EX AF, AF'";
else if (y == 2) {
op_name = "DJNZ %d";
state = DISP;
} else if (y == 3) {
op_name = "JR %d";
state = DISP;
} else {
sprintf (op_buf, "JR %s, %%02x", table_cc[y-4]);
op_name = op_buf;
state = IMM1;
}
break;
case 1 :
if (opcode.bit(3)) {
sprintf (op_buf, "ADD HL, %s", table_rp[y>>1]);
op_name = op_buf;
} else {
sprintf (op_buf, "LD %s, %%04x", table_rp[y>>1]);
op_name = op_buf;
state = IMM2;
}
break;
case 2 :
switch (y) {
case 0 : op_name = "LD (BC), A"; break;
case 1 : op_name = "LD (DE), A"; break;
case 2 : op_name = "LD (%04x), HL"; state = IMM2; break;
case 3 : op_name = "LD (%04x), A"; state = IMM2; break;
case 4 : op_name = "LD A, (BC)"; break;
case 5 : op_name = "LD A, (DE)"; break;
case 6 : op_name = "LD HL, (%04x)"; state = IMM2; break;
case 7 : op_name = "LD A, (%02x)"; state = IMM1; break;
}
break;
case 3 :
if (opcode.bit(3)) {
sprintf (op_buf, "DEC %s", table_rp[opcode.range(5,4)]);
op_name = op_buf;
} else {
sprintf (op_buf, "INC %s", table_rp[opcode.range(5,4)]);
op_name = op_buf;
}
break;
case 4 :
sprintf (op_buf, "INC %s", table_r[y]);
op_name = op_buf;
break;
case 5 :
sprintf (op_buf, "DEC %s", table_r[y]);
op_name = op_buf;
break;
case 6 :
sprintf (op_buf, "LD %s, %%02x", table_r[y]);
op_name = op_buf;
state = IMM1;
break;
case 7 :
switch (y) {
case 0 : op_name = "RLCA"; break;
case 1 : op_name = "RRCA"; break;
case 2 : op_name = "RLA"; break;
case 3 : op_name = "RRA"; break;
case 4 : op_name = "DAA"; break;
case 5 : op_name = "CPL"; break;
case 6 : op_name = "SCF"; break;
case 7 : op_name = "CCF"; break;
}
break;
}
break;
case 1 :
if ((z == 6) && (y == 6)) {
op_name = "HALT";
} else {
sprintf (op_buf, "LD %s, %s", table_r[y], table_r[z]);
op_name = op_buf;
}
break;
case 2 : // ALU
sprintf (op_buf, "%s %s", table_alu[y], table_r[z]);
op_name = op_buf;
break;
case 3 :
switch (z) {
case 0 :
sprintf (op_buf, "RET %s", table_cc[y]);
op_name = op_buf;
break;
case 1 : // TBD, POP & opcodes
switch (y) {
case 0 : case 1: case 2 : case 3 :
sprintf (op_buf, "POP %s", table_rp2[y>>1]);
op_name = op_buf;
break;
case 4 : op_name = "RET"; break;
case 5 : op_name = "EXX"; break;
case 6 : op_name = "JP HL"; break;
case 7 : op_name = "LD SP, HL"; break;
}
break;
case 2 :
sprintf (op_buf, "JP %s, %%04x", table_cc[y]);
op_name = op_buf;
state = IMM2;
break;
case 3 : // JP and opcodes
switch (y) {
case 0 : op_name = "JP %04x"; state = IMM2; break;
case 1 : state = PRE_CB; break;
case 2 : op_name = "OUT (%02x), A"; state = IMM1; break;
case 3 : op_name = "IN A, (%02x)"; state = IMM1; break;
case 4 : op_name = "EX (SP), HL"; break;
case 5 : op_name = "EX DE, HL"; break;
case 6 : op_name = "DI"; break;
case 7 : op_name = "EI"; break;
}
break;
case 4 :
sprintf (op_buf, "CALL %s, %%04x", table_cc[y]);
op_name = op_buf;
state = IMM2;
break;
case 5 :
switch (y) {
case 0 :
case 1 :
case 2 :
case 3 :
sprintf (op_buf, "PUSH %s", table_rp2[y>>1]);
op_name = op_buf;
break;
case 4 :
op_name = "CALL %04x";
state = IMM2;
break;
case 5 : state = PRE_DD; break;
case 6 : state = PRE_ED; break;
case 7 : state = PRE_FD; break;
}
break;
}
break;
}
/*FOR x=0
z=0
y=0 NOP y=2 DJNZ d
y=1 EX AF, AF' y=3 JR d
y=4..7 JR cc[y-4], d
Relative jumps and assorted ops
z=1
q=0 LD rp[p], nn
q=1 ADD HL, rp[p]
16-bit load immediate/add
z=2
q=0 p=0 LD (BC), A p=2 LD (nn), HL
p=1 LD (DE), A p=3 LD (nn), A
q=1 p=0 LD A, (BC) p=2 LD HL, (nn)
p=1 LD A, (DE) p=3 LD A, (nn)
Indirect loading
z=3
q=0 INC rp[p]
q=1 DEC rp[p]
16-bit INC/DEC
z=4
INC r[y]
8-bit INC
z=5
DEC r[y]
8-bit DEC
z=6
LD r[y], n
8-bit load immediate
z=7
y=0 RLCA y=4 DAA
y=1 RRCA y=5 CPL
y=2 RLA y=6 SCF
y=3 RRA y=7 CCF
Assorted operations on accumulator/flags
*/
if (state == UNPRE) {
//printf ("DECODE : %02x %s\n", (int) opcode, op_name);
op_print();
}
}
 
void z80_decoder::event()
{
if ((en_decode == false) || !reset_n) return;
if (!m1_n && !mreq_n && !rd_n && wait_n) {
imm = 0;
op_addr = (int) addr;
switch ( (int) di.read() ) {
case 0xCB : state = PRE_CB; break;
case 0xDD : state = PRE_DD; break;
case 0xED : state = PRE_ED; break;
case 0xFD : state = PRE_FD; break;
default :
opcode = di;
state = UNPRE;
decode_unpre();
break;
}
} else if (!mreq_n && !rd_n && wait_n && (state != UNPRE)) {
switch (state) {
case IMM2 :
imm = ((unsigned int) di) & 0xff;
state = IMM2B;
break;
case IMM2B :
imm |= ((unsigned int) di << 8)& 0xFF00;
sprintf (op_buf, op_name, imm);
op_name = op_buf;
op_print();
break;
case IMM1 :
imm = ((unsigned int) di) & 0xff;
sprintf (op_buf, op_name, imm);
//printf ("DECODE : %02x %s\n", (int) opcode, op_name);
op_name = op_buf;
op_print();
break;
}
}
}
/z80_decoder.h
0,0 → 1,40
#ifndef Z80_DECODER_H_
#define Z80_DECODER_H_
 
#include "systemc.h"
 
typedef enum { UNPRE, PRE_CB, PRE_DD, PRE_ED, PRE_FD, DISP, IMM1, IMM2, IMM2B } dec_state;
SC_MODULE(z80_decoder)
{
private:
dec_state state;
sc_uint<8> opcode;
char *op_name;
char op_buf[80];
uint16_t imm, op_addr;
void decode_unpre();
void op_print();
public:
sc_in<bool> clk;
sc_in<uint32_t> addr;
sc_in<bool> m1_n;
sc_in<bool> mreq_n;
sc_in<bool> rd_n;
sc_in<bool> wait_n;
sc_in<uint32_t> di;
sc_in<bool> reset_n;
bool en_decode;
 
void event();
SC_CTOR(z80_decoder) {
SC_METHOD (event);
sensitive << clk.pos();
en_decode = false;
}
};
 
#endif /*Z80_DECODER_H_*/
/Makefile
4,7 → 4,7
INCLUDES=-I$(SYSTEMC)/include -I$(VERIDIR) -I$(VERILATOR_ROOT)/include -I$(SYSTEMPERL)
LINKOPT=-L$(SYSTEMC)/lib-linux64 -lsystemc -lm
DEFINES=-DDEBUG
OBJFILES=sc_env_top.o env_memory.o tv_responder.o \
OBJFILES=sc_env_top.o env_memory.o tv_responder.o z80_decoder.o \
$(VERIDIR)/Vtv80s.o $(VERIDIR)/Vtv80s__Syms.o \
$(VERIDIR)/Vtv80s__Trace.o \
$(VERIDIR)/Vtv80s__Trace__Slow.o \

powered by: WebSVN 2.1.0

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