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

Subversion Repositories tv80

[/] [tv80/] [trunk/] [sc_env/] [tv_responder.cpp] - Rev 111

Compare with Previous | Blame | View Log

#include "tv_responder.h"
 
uint64_t get_time_stamp () {
	sc_time t;
 
	t = sc_time_stamp();
	return t.value();
}
 
void tv_responder::event ()
{
	// init
	//reset_n = 0;
	/*
	wait_n = 1;
	int_n = 1;
	nmi_n = 1;
	busrq_n = 1;
	di_resp = 0;
	*/
	uint8_t oldval;
 
	if (reset_time > 0) {
		reset_n = 0;
	    wait_n = 1;
		int_n = 1;
		nmi_n = 1;
		busrq_n = 1;
		di_resp = 0;
		reset_time--;
		if (reset_time == 0)
			printf ("Initialization complete.\n");
		return;
	} else {
		if (reset_time == 0) {
			reset_n = 1;
			reset_time--;
		}
	}
 
 
    if (!iorq_n & !rd_n)
        {
          switch (addr) {
            case (0x82) : di_resp = timeout_ctl; break;
	  		case(0x83) : di_resp = max_timeout & 0xff; break;
	   		case(0x84) : di_resp = max_timeout >> 8; break;
 
	    	case(0x90) : di_resp = int_countdown; break;
            case(CKSUM_VALUE) : 
            	di_resp = checksum; 
				//printf ("%2.6f: Read checksum value of %02x\n", sc_time_stamp().to_seconds(), checksum);
            	break;
            case(0x93) : di_resp = ior_value; break;
            case(0x94) : di_resp = rand();  break;
            case(0x95) : di_resp = nmi_countdown; break;
            case(0xA0) : di_resp = nmi_trigger; break;
            default : di_resp = 0;
          }
        } // if (!iorq_n & !rd_n)
 
//  wire wr_stb;
//  reg last_iowrite;
 
//  assign wr_stb = (!iorq_n & !wr_n);
 
//  always @(posedge clk)
//   begin
      //last_iowrite <= #1 wr_stb;
    //if (!iorq_n && !wr_n)
    //	printf ("DEBUG:  I/O Write detected addr=%02x\n", 0xff & (int) addr.read());
 
    if (!iorq_n && !wr_n && !last_iowrite) {
    	int l_dout, l_addr;
 
    	l_addr = addr.read();
    	l_dout = dout.read();
 
      	last_iowrite = true;
		switch ( l_addr & 0xff) {
			case(SIM_CTL_PORT) :
			// dump control deprecated
			if (l_dout == 1) {
				printf ("%2.6f: --- TEST PASSED ---\n", sc_time_stamp().to_seconds());
				sc_stop();
			} else if (l_dout == 2) {
				printf ("%2.6f: !!! TEST FAILED !!!\n", sc_time_stamp().to_seconds());
				sc_stop();
			}
			break;
 
			case(MSG_PORT) :
 
	      		if (l_dout == 0x0A) {
					printf ("%2.6f: PROGRAM : ", sc_time_stamp().to_seconds());
 
					for (int i=0; i<buf_ptr; i=i+1)
						printf ("%c", str_buf[i]);
 
					printf ("\n");
		 			buf_ptr = 0;
				} else {
	      			str_buf[buf_ptr] = (char) (l_dout & 0xff);
	      			buf_ptr = buf_ptr + 1;
	      		}
		    break;
 
			case(TIMEOUT_PORT) :
		    	timeout_ctl = l_dout;
				break;
 
			case(MAX_TIMEOUT_LOW) :
				max_timeout = l_dout | (max_timeout & 0xFF00);
				break;
 
			case(MAX_TIMEOUT_HIGH) :
				max_timeout = (l_dout << 8) | (max_timeout & 0x00FF);
				printf ("%2.6f: ENVIRON : Timeout reset to %d (dout=%d)\n", sc_time_stamp().to_seconds(), max_timeout, l_dout);
				break;
 
			case(0x90) : int_countdown = dout; break;
			case(CKSUM_VALUE) : checksum = dout; break;
			case(CKSUM_ACCUM) : 
				oldval = checksum;
				checksum = checksum + dout; 
				//printf ("%2.6f: ENVIRON : cksum %02x=%02x + %02x\n", sc_time_stamp().to_seconds(), checksum, oldval, l_dout);
				break;
			case(0x93) : ior_value = dout; break;
			case(0x95) : nmi_countdown = dout; break;
			case(0xA0) : nmi_trigger = dout; break;
		}
    } else if (iorq_n)
    	last_iowrite = false;
 
	if (timeout_ctl & 0x2) {
		cur_timeout = 0;
		timeout_ctl = timeout_ctl & 1;
	} else if (timeout_ctl & 0x1)
		cur_timeout = cur_timeout + 1;
 
    if (cur_timeout >= max_timeout) {
	  printf ("%2.6f: ERROR   : Reached timeout %d cycles\n", sc_time_stamp().to_seconds(), max_timeout);
	  //tb_top.test_fail;
	  sc_stop();
    }
 
	if (int_countdown == 0) {
		int_n = 1;
	} else if (int_countdown == 1)
		int_n  = 0;
    else if (int_countdown > 1) {
	  int_countdown = int_countdown - 1;
	  int_n  = 1;
    }
 
    // when nmi countdown reaches 1, an NMI will be issued.
    // to clear the interrupt, write nmi_countdown to 0.
    if ((nmi_countdown == 0) && (nmi_trigger == 0))
		nmi_n = 1;
    else if (nmi_countdown == 1)
		nmi_n = 0;
    else if (nmi_countdown > 1) {
		nmi_countdown = nmi_countdown - 1;
		nmi_n = 1;
    }
 
    // when IR equals the target instruction, an NMI will be
    // issued.  To clear the interrupt, write nmi_trigger to
    // zero.
    /*  can't do this in systemc
    if (nmi_trigger != 0) {
          if (nmi_trigger === tb_top.tv80s_inst.i_tv80_core.IR[7:0])
            begin
              tb_top.nmi_n <= #80 0;
              tb_top.nmi_n <= #160 1;
            end
    } else if (nmi_countdown == 0)
        nmi_n = 1;
     */
}
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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