⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cc

📁 一个mips虚拟机非常好代码,使用C++来编写的,希望大家多学学,
💻 CC
字号:
// Zilog Enhanced Serial Communication Controller// Matt Chapman <matthewc@cse.unsw.edu.au>//// NOTE: This is only a basic implementation, designed for usage as a console.#include <stdio.h>#include <string.h>#include <unistd.h>#include <assert.hh>#include <checkpoint.hh>#include <device.hh>#include <inttypes.hh>#include <module.hh>#include <serial.hh>#include <simarg.hh>#include <sulima.hh>#include <fcntl.h>#include "escc.hh"// Serialization information.SerialType<ZilogESCC> ZilogESCC::type(    "ZilogESCC",    "Zilog Enhanced Serial Communication Controller");// Runtime constructor.ZilogESCC::ZilogESCC(const SimArgs& args)    : Module(args), Device(8){    if (args.length() > 2)	throw Error("Too many arguments to \"sim::install ZilogESCC\".");    define("irq", conf.irq);    define("debugirq", conf.debugirq);}// Serialized constructor.ZilogESCC::ZilogESCC(Checkpoint& cp)    : Module(cp), Device(8){    reset(false);}// Module interface.voidZilogESCC::reset(bool warm){    intr_enable = false;    intr_pending = intr_mask = intr_vector = intr_ius = 0;    for (int i = 0; i < 2; i++)	rx_lo[i] = rx_hi[i] = 0;    reg = 0;    status_poll = 0;    setup_pty();}// Serialization interface.voidZilogESCC::checkpoint(Checkpoint& cp, bool parent) const{}// Reported Interrupt Under Service codes for each sourceconst UInt8 ZilogESCC::intr_ius_map[] = { 3 /* none */, 1, 0, 2, 5, 4, 6 };voidZilogESCC::check_interrupts(void){    if (intr_enable && (intr_pending & intr_mask)) {	// select highest priority interrupt	intr_ius = intr_ius_map[ffs(intr_pending & intr_mask)];	intctrl->deliver_interrupt(conf.irq);    }    else {	intr_ius = intr_ius_map[0];	intctrl->clear_interrupt(conf.irq);    }}ClockValueZilogESCC::read(UInt64 addr, UInt64* buf, int size){    UInt8 cmddata, channel;    assert(size > 0 && size <= 8);    assert(!is_power_of_two(size) || (addr & (size - 1)) == 0);    cmddata = bit(addr, 0);    channel = bit(addr, 1);    if (cmddata == Data) {	// collect next character	*buf = rx_fifo[channel][rx_lo[channel]];	if (rx_lo[channel] != rx_hi[channel])	    rx_lo[channel] = (rx_lo[channel]+1) & rx_fifo_mask;	if (rx_lo[channel] == rx_hi[channel]){	    intr_pending &= ~ ( (channel == ChannelA) ? RxIntrA : RxIntrB);	    check_interrupts();	}	return 0;    }    switch (reg) {    case 0: // Transmit/Receive Buffer Status and External Status */	*buf = (1 << 2); // Tx buffer empty	if (rx_lo[channel] != rx_hi[channel])		*buf |= (1 << 0); // Rx char available	// Upon polling the status register 10 times without an intervening write,	// assume that we are waiting for input and flush output to user.	if (++status_poll == 10)		fflush(stdout);	break;    case 2: // Interrupt Vector	if (channel == ChannelA)	    *buf = intr_vector;	else	    *buf = intr_vector | (intr_ius << 1);	break;    case 3: // Interrupt Pending	if (channel == ChannelA)	    *buf = intr_pending;	else	    *buf = 0;	break;    default:	//log("read unimplemented register %d", reg);	*buf = 0;	break;    }    reg = 0;    return 0; // ignore latency}ClockValueZilogESCC::write(UInt64 addr, const UInt64* buf, int size){    UInt8 cmddata, channel, value;    UInt8 command, mask, newreg = 0;    assert(size > 0 && size <= 8);    assert(!is_power_of_two(size) || (addr & (size - 1)) == 0);    cmddata = bit(addr, 0);    channel = bit(addr, 1);    value = *buf & 0xff;    if (cmddata == Data) {	status_poll = 0;	if (channel == ChannelA)		putchar(value);	else		::write(io_fd, &value, 1);	// all sent, now the Tx buffer is empty...	intr_pending |= (channel == ChannelA) ? TxIntrA : TxIntrB;	check_interrupts();	return 0;    }    switch (reg) {    case 0: /* Command Register */	newreg = bits(value, 2, 0);	command = bits(value, 5, 3);	switch (command) {	case 0:		/* null cmd */	    break;	case 1:		/* point high */	    newreg += 8;	    break;	case 5:		/* clear Tx int */	    intr_pending &= ~((channel == ChannelA) ? TxIntrA : TxIntrB);	    check_interrupts();	    break;	case 7:		/* reset highest IUS */	    check_interrupts();	    break;	default:	    log("unsupported command %d", command);	    break;	}	command = bits(value, 7, 6);	switch (command) {	case 0:		/* null cmd */	    break;	default:	    log("unsupported CRC command %d", command);	    break;	}	break;    case 1: // Transmit/Receive Interrupt and Data Transfer Mode Definition	mask = bits(value, 1, 0);	// transmit, external/status	if (bit(value, 3) ^ bit(value, 4))	// (01 or 10)	    mask |= 1 << 2;	// receive	if (channel == ChannelA) {	    intr_mask &= ~(RxIntrA | TxIntrA | ExtIntrA);	    intr_mask |= mask << 3;	}	else {	    intr_mask &= ~(RxIntrB | TxIntrB | ExtIntrB);	    intr_mask |= mask;	}	break;    case 2: // Interrupt Vector	intr_vector = value;	break;    case 9: // Master Interrupt Enable	intr_enable = bit(value, 3);	break;    default:	//log("write unimplemented register %d", reg);	break;    }    reg = newreg;    return 0; // ignore latency}voidZilogESCC::input(int c, int channel){    UInt8 new_rx_hi;    static bool debug;    if (debug) {	intctrl->clear_interrupt(conf.debugirq);	debug = false;    } else {	switch (c) {	    case 4:	// Ctrl-D - DEBUG		intctrl->deliver_interrupt(conf.debugirq);		debug = true;		return;	    case 18:	// Ctrl-R - DUMP REGISTERS		bus->clock->dump_state();		return;	}    }    rx_fifo[channel][rx_hi[channel]] = (UInt8)c;    new_rx_hi = (rx_hi[channel]+1) & rx_fifo_mask;    if (new_rx_hi != rx_lo[channel])	rx_hi[channel] = new_rx_hi;    intr_pending |= (channel == ChannelA) ? RxIntrA : RxIntrB;    check_interrupts();}voidZilogESCC::input(int c){    input(c, ChannelA);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -