// Filename : input_reader.cpp
//
// This file was initially generated by SpaceStudio but is meant to be modified
// by the user.
#include "input_reader.h"
#include "spacecomp_pre_cpp.h"

#ifndef SPACE_ARCHITECTURE_IMPLEMENTATION
static void module_stop(void* opaque) {
	input_reader* self = (input_reader*)opaque;
	self->stop_simulation();
}
#endif

input_reader::input_reader(SPACECOMP_CTOR_PARAMS(input_reader, INDEX))
	: abstract_module(SPACECOMP_MBASE_ARGS(input_reader, INDEX))
	, SPACECOMP_START_ILIST(input_reader, INDEX)
	// Other initializers may go here
{
	SPACECOMP_THREAD(input_reader, INDEX, thread);
	request_stack(16 * 1024);

#ifdef SPACE_ARCHITECTURE_IMPLEMENTATION
m_reading = true;
m_size = 0;
#else
	callback callbacks = { this, &module_stop };
	m_generator.set_callbacks(callbacks);
#endif
}

#ifndef SPACE_ARCHITECTURE_IMPLEMENTATION
void input_reader::stop_simulation() {
	sc_stop();
}
#endif

void input_reader::thread(SPACECOMP_THREAD_PARAMS(input_reader, INDEX, thread)) {
	spacecomp_thread_initialize();

	while (1) {
		const bool initializing = spacecomp_thread_loop_start();
		if (initializing) {}
		send_to_fifo(read_uart());
	}
}

uint8_t input_reader::read_uart() {
	#ifdef SPACE_ARCHITECTURE_IMPLEMENTATION
		if(m_reading) {
			m_size = 0;
			std::cin >> m_input;
			m_reading = false;
		}

		if(m_size < m_input.size()){
			return m_input[m_size++];
		}

		if(m_size == m_input.size()){
			m_reading = true;
			// Char indicating end of expression
			return 0XA;
		}
	#else
		return m_generator.get_character();
	#endif
}

void input_reader::send_to_fifo(uint8_t character) {
	uint32_t data = character;
	ModuleWrite(CONTROLLER0_ID, SPACE_BLOCKING, data);
}

#include "spacecomp_post_cpp.h"
