Exemple #1
0
// IEC Send byte standard function
//
// Sends the byte and can signal EOI
//
boolean IEC::sendByte(byte data, boolean signalEOI)
{
	// Listener must have accepted previous data
	if(timeoutWait(m_dataPin, true))
		return false;

	// Say we're ready
	writeCLOCK(false);

	// Wait for listener to be ready
	if(timeoutWait(m_dataPin, false))
		return false;

	if(signalEOI) {
		// TODO: Make this like sd2iec and may not need a fixed delay here.

		// Signal eoi by waiting 200 us
		delayMicroseconds(TIMING_EOI_WAIT);

		// get eoi acknowledge:
		if(timeoutWait(m_dataPin, true))
			return false;

		if(timeoutWait(m_dataPin, false))
			return false;
	}

	delayMicroseconds(TIMING_NO_EOI);

	// Send bits
	for(byte n = 0; n < 8; n++) {
		// TODO: Here check whether data pin goes low, if so end (enter cleanup)!

		writeCLOCK(true);
		// set data
		writeDATA((data bitand 1) ? false : true);

		delayMicroseconds(TIMING_BIT);
		writeCLOCK(false);
		delayMicroseconds(TIMING_BIT);

		data >>= 1;
	}

	writeCLOCK(true);
	writeDATA(false);

	// TODO: Maybe make the following ending more like sd2iec instead.

	// Line stabilization delay
	delayMicroseconds(TIMING_STABLE_WAIT);

	// Wait for listener to accept data
	if(timeoutWait(m_dataPin, true))
		return false;

	return true;
} // sendByte
Exemple #2
0
void X86::declareMatrix(int decl_type, int type, string name, list<string> dims) {
  int size = 1;
  for(list<string>::iterator it = dims.begin(); it != dims.end(); it++) {
    size *= atoi((*it).c_str());
  }


  if(decl_type == VAR_GLOBAL) {
    stringstream s;
    switch(type) {
      case TIPO_INTEIRO:
      case TIPO_REAL:
      case TIPO_CARACTERE:
      case TIPO_LOGICO:
      case TIPO_LITERAL:
        s << X86::makeID(name) << " times " << size << " dd 0";
        break;
      default:
        GPTDisplay::self()->showError("Erro interno: tipo nao suportado (X86::declarePrimitive).");
        exit(1);
    }
    writeDATA(s.str());
  } else if(decl_type == VAR_PARAM) {
    _subprograms[currentScope()].declareParam(name, type, size);
  } else if(decl_type == VAR_LOCAL) {
    _subprograms[currentScope()].declareLocal(name, size);
  } else {
    GPTDisplay::self()->showError("Erro interno: X86::declareMatrix).");
    exit(1);
  }
}
Exemple #3
0
byte IEC::timeoutWait(byte waitBit, boolean whileHigh)
{
	word t = 0;
	boolean c;

	while(t < TIMEOUT) {
		// Check the waiting condition:
		c = readPIN(waitBit);

		if(whileHigh)
			c = not c;

		if(c)
			return false;

		delayMicroseconds(2); // The aim is to make the loop at least 3 us
		t++;
	}

	// If down here, we have had a timeout.
	// Release lines and go to inactive state with error flag
	writeCLOCK(false);
	writeDATA(false);

	m_state = errorFlag;

	// Wait for ATN release, problem might have occured during attention
	while(!readATN());

	// Note: The while above is without timeout. If ATN is held low forever,
	//       the CBM is out in the woods and needs a reset anyways.

	return true;
} // timeoutWait
Exemple #4
0
string X86::addGlobalLiteral(string str) {
  stringstream s;
  string lb = createLabel(false, "str");
  s << lb << " db '" << toNasmString(str) << "',0";
  writeDATA(s.str());
  return lb;
}
Exemple #5
0
void X86::declarePrimitive(int decl_type, const string& name, int type) {
  stringstream s;
  if(decl_type == VAR_GLOBAL) {
    //all sizes have 32 bits (double word)
    switch(type) {
      case TIPO_INTEIRO:
      case TIPO_REAL:
      case TIPO_CARACTERE:
      case TIPO_LITERAL:
      case TIPO_LOGICO:
        s << X86::makeID(name) << " dd 0";
        writeDATA(s.str());
        break;
      default:
        GPTDisplay::self()->showError("Erro interno: tipo nao suportado (X86::declarePrimitive).");
        exit(1);
    }
  } else if(decl_type == VAR_PARAM) {
    _subprograms[currentScope()].declareParam(name, type);
  } else if(decl_type == VAR_LOCAL) {
    _subprograms[currentScope()].declareLocal(name);
  } else {
    GPTDisplay::self()->showError("Erro interno: X86::declarePrimitive).");
    exit(1);
  }
}
Exemple #6
0
//-------------------------------------------------------------------------------------------------------------------
void bytebuffer::writeUSTRING(const wchar_t* string)
{
    unsigned int size;
    for(size = 0;string[size] != 0;size++)
        ;
    writeINT(size);
    writeDATA((char*)string,size *2);
}
Exemple #7
0
//-------------------------------------------------------------------------------------------------------------------
void bytebuffer::writeASTRING(const char* string)
{
    unsigned int size;
    for(size = 0;string[size] != '\0';size++)
        ;
    writeSHORT(size);
    writeDATA(string,size);
}
Exemple #8
0
//-------------------------------------------------------------------------------------------------------------------
void bytebuffer::writeUSTRING(const char* string)
{
    unsigned int size;
    for(size = 0;string[size] != '\0';size++)
        ;
    wchar_t* new_string = new wchar_t[size];
    ascii_to_unicode(new_string,string,size);
    writeINT(size);
    writeDATA((char*)new_string,size *2);
    delete [] new_string;
}
Exemple #9
0
//-------------------------------------------------------------------------------------------------------------------
void bytebuffer::writeASTRING(const wchar_t* string)
{
    unsigned int size;
    for(size = 0;string[size] != 0;size++)
        ;
    char* new_string = new char[size];
    unicode_to_ascii(new_string,string,size);
    writeSHORT(size);
    writeDATA(new_string,size);
    delete [] new_string;
}
Exemple #10
0
// A special send command that informs file not found condition
//
boolean IEC::sendFNF()
{
	// Message file not found by just releasing lines
	writeDATA(false);
	writeCLOCK(false);

	// Hold back a little...
	delayMicroseconds(TIMING_FNF_DELAY);

	return true;
} // sendFNF
Exemple #11
0
// this routine will set the direction on the bus back to normal
// (the way it was when the computer was switched on)
boolean IEC::undoTurnAround(void)
{
	writeDATA(true);
	delayMicroseconds(TIMING_BIT);
	writeCLOCK(false);
	delayMicroseconds(TIMING_BIT);

	// wait until the computer releases the clock line
	if(timeoutWait(m_clockPin, true))
		return false;

	return true;
} // undoTurnAround
Exemple #12
0
// IEC turnaround
boolean IEC::turnAround(void)
{
	// Wait until clock is released
	if(timeoutWait(m_clockPin, false))
		return false;

	writeDATA(false);
	delayMicroseconds(TIMING_BIT);
	writeCLOCK(true);
	delayMicroseconds(TIMING_BIT);

	return true;
} // turnAround
Exemple #13
0
void IEC::testOUTPUTS()
{
	static bool lowOrHigh = false;
	unsigned long now = millis();
	// switch states every second.
	if(now - m_lastMillis >= 1000) {
		m_lastMillis = now;
		char buffer[80];
		sprintf(buffer, "Lines: CLOCK: %s DATA: %s", (lowOrHigh ? "HIGH" : "LOW"), (lowOrHigh ? "HIGH" : "LOW"));
		Log(Information, FAC_IEC, buffer);
		writeCLOCK(lowOrHigh);
		writeDATA(lowOrHigh);
		lowOrHigh ^= true;
	}
} // testOUTPUTS
Exemple #14
0
string X86::source() {
  stringstream str;

  //.data footer
  writeDATA("datasize   equ     $ - data_no");

  str << _head.str()
      << _bss.str()
      << _data.str();

  //.text header
  str << "section .text" << endl;
  str << "start_no equ $" << endl;

  string sss;
  for(map<string, X86SubProgram>::iterator it = _subprograms.begin(); it != _subprograms.end(); ++it) {
    sss = it->second.source();
    str << it->second.source();
  }

  str  << _lib.str();

  return str.str();
}
Exemple #15
0
// This function checks and deals with atn signal commands
//
// If a command is recieved, the cmd-string is saved in cmd. Only commands
// for *this* device are dealt with.
//
// Return value, see IEC::ATNCheck definition.
IEC::ATNCheck IEC::checkATN(ATNCmd& cmd)
{
	ATNCheck ret = ATN_IDLE;
	byte i = 0;

	if(not readATN()) {
		// Attention line is active, go to listener mode and get message
		writeDATA(true);
		writeCLOCK(false);
#ifdef CONSOLE_DEBUG
		//Log(Information, FAC_IEC, "ATT.ACTIVE");
#endif

		delayMicroseconds(TIMING_ATN_PREDELAY);

		// Get first ATN byte, it is either LISTEN or TALK
		ATNCommand c = (ATNCommand)receiveByte();
		if(m_state bitand errorFlag)
			return ATN_ERROR;

		if(c == (ATN_CODE_LISTEN bitor m_deviceNumber)) {
			// Okay, we will listen.
#ifdef CONSOLE_DEBUG
			//Log(Information, FAC_IEC, "LISTEN");
#endif

			// Get the first cmd byte, the cmd code
			c = (ATNCommand)receiveByte();
			if (m_state bitand errorFlag)
				return ATN_ERROR;

			//Log(Information, FAC_IEC, "CODE");
			cmd.code = c;

			if((c bitand 0xF0) == ATN_CODE_DATA) {
				// A heapload of data might come now, client handles this
				//Log(Information, FAC_IEC, "LDATA");
				ret = ATN_CMD_LISTEN;
			}
			else if(c not_eq ATN_CODE_UNLISTEN) {
#ifdef CONSOLE_DEBUG
				//Log(Information, FAC_IEC, "CMD");
#endif
				// Some other command. Record the cmd string until UNLISTEN is send
				for(;;) {
					c = (ATNCommand)receiveByte();
					if(m_state bitand errorFlag)
						return ATN_ERROR;

					if((m_state bitand atnFlag) and (c == ATN_CODE_UNLISTEN))
						break;

					if(i >= ATN_CMD_MAX_LENGTH) {
						// Buffer is going to overflow, this is an error condition
						return ATN_ERROR;
					}
					cmd.str[i++] = c;
				}
				ret = ATN_CMD;
			}
		}
		else if (c == (ATN_CODE_TALK bitor m_deviceNumber)) {
			// Okay, we will talk soon, record cmd string while ATN is active
#ifdef CONSOLE_DEBUG
			//Log(Information, FAC_IEC, "TALK");
#endif
			// First byte is cmd code
			c = (ATNCommand)receiveByte();
			if(m_state bitand errorFlag)
				return ATN_ERROR;
			cmd.code = c;

			while(not readATN()) {
				if(readCLOCK()) {
					c = (ATNCommand)receiveByte();
					if(m_state bitand errorFlag)
						return ATN_ERROR;

					if(i >= ATN_CMD_MAX_LENGTH) {
						// Buffer is going to overflow, this is an error condition
						return ATN_ERROR;
					}
					cmd.str[i++] = c;
				}
			}

			// Now ATN has just been released, do bus turnaround
			if(!turnAround())
				return ATN_ERROR;

			// We have recieved a CMD and we should talk now:
			ret = ATN_CMD_TALK;

		}
		else {
			// Either the message is not for us or insignificant, like unlisten.
			delayMicroseconds(TIMING_ATN_DELAY);
			writeDATA(false);
			writeCLOCK(false);
//			{
//				char buffer[20];
//				sprintf(buffer, "NOTUS: %u", c);
//				Log(Information, FAC_IEC, buffer);
//			}

			// Wait for ATN to release and quit
			while(not readATN());
			//Log(Information, FAC_IEC, "ATNREL");
		}
	}
	else {
		// No ATN, release lines
		writeDATA(false);
		writeCLOCK(false);
	}

	// some delay is required before more ATN business
	delayMicroseconds(TIMING_ATN_DELAY);

	cmd.strlen = i;
	return ret;
} // checkATN
Exemple #16
0
// IEC Recieve byte standard function
//
// Returns data recieved
// Might set flags in iec_state
//
// TODO: m_iec might be better returning bool and returning read byte as reference in order to indicate any error.
byte IEC::receiveByte(void)
{
	m_state = noFlags;

	// Wait for talker ready
	if(timeoutWait(m_clockPin, false)) {
#ifdef CONSOLE_DEBUG
//		Log(Information, FAC_IEC, "T1");
#endif
		return 0;
	}

	// Say we're ready
	writeDATA(false);

	// Record how long CLOCK is high, more than 200 us means EOI
	byte n = 0;
	while(readCLOCK() and (n < 20)) {
		delayMicroseconds(10);  // this loop should cycle in about 10 us...
		n++;
	}

	if(n >= TIMING_EOI_THRESH) {
		// EOI intermission
		m_state or_eq eoiFlag;

		// Acknowledge by pull down data more than 60 us
		writeDATA(true);
		delayMicroseconds(TIMING_BIT);
		writeDATA(false);

		// but still wait for clk
		if(timeoutWait(m_clockPin, true)) {
#ifdef CONSOLE_DEBUG
//			Log(Information, FAC_IEC, "T2");
#endif
			return 0;
		}
	}

	// Sample ATN
	if(false == readATN())
		m_state or_eq atnFlag;

	byte data = 0;
	// Get the bits, sampling on clock rising edge:
	for(n = 0; n < 8; n++) {
		data >>= 1;
		if(timeoutWait(m_clockPin, false)) {
#ifdef CONSOLE_DEBUG
//			Log(Information, FAC_IEC, "T3");
#endif
			return 0;
		}
		data or_eq (readDATA() ? (1 << 7) : 0);
		if(timeoutWait(m_clockPin, true)) {
#ifdef CONSOLE_DEBUG
//			Log(Information, FAC_IEC, "T4");
#endif
			return 0;
		}
	}

	// Signal we accepted data:
	writeDATA(true);

	return data;
} // receiveByte
Exemple #17
0
//-------------------------------------------------------------------------------------------------------------------
void bytebuffer::writeBUFFER(bytebuffer *data)
{
    writeDATA(data->getBuffer(),data->getSize());
}