/*
 * sys_prog.c
 *
 *  Created on: 2016/12/15
 *      Author: takayun
 */

#include "sys_prog.h"
#include <stdio.h>
#include "sys_debug.h"
#include "sys_register.h"
#include "sys_memory.h"
#include "hex_out.h"
#include "lcd_out.h"

unsigned int inc_pc() {
	if ((unsigned char)global_registers[Spc]+1 < MEM_SIZE*MEMS_COUNT - global_current_memory*MEM_SIZE ) {
		global_registers[Spc] = (unsigned char)global_registers[Spc] + 1;
	} else {
		global_registers[Spc] = 0;
	}
	return 0;
}
unsigned int add_pc(unsigned int cnt) {
	int i;
	for (i = 0; i < cnt; i++) inc_pc();
	return 0;
}
unsigned int set_pc(unsigned int cnt) {
	global_registers[Spc]=cnt;
	return 0;
}
unsigned int get_pc() {
	if ((unsigned char)global_registers[Spc] < MEM_SIZE*MEMS_COUNT - global_current_memory*MEM_SIZE ) {
		return (unsigned int)((unsigned char)global_registers[Spc]);
	} else {
		return 0;
	}
}

enum RunMode run_proc(enum RunMode mode) {
	volatile struct InstRec inst_rec;

	if (RUN_INIT == mode) {
		lcd_caret_reset();
		lcd_print("Run...now");

		global_registers[Spc] = 0;
		clear_block(HEX0_3); clear_block(HEX4_5); clear_block(HEX6_7);

		// プログラム実行中へ遷移
		return RUN_PROC;
	}

	if (RUN_PROC == mode) {
		// 命令フェッチ
		inst_rec = inst_fetch();
		// 命令デコード実行
		inst_decode(inst_rec);
		// pc表示
		{
			char buf[5];
			sprintf(buf, "%02x", (unsigned char)global_registers[Spc]);
			print_block("pc", 2, HEX6_7);
			print_block(buf, 2, HEX4_5);
		}

		// デバック用
		if ( global_registers[Ssw_run] ) delay10ms(100U);

		// プログラム終了判定
		if (inst_rec.inst != INST_END) return RUN_PROC;
		return RUN_TERM;
	}

	if (RUN_TERM == mode) {
		lcd_caret_reset();
		lcd_print("Run...Exit");
		return RUN_STOP;
	}

	// Default
	return RUN_STOP;
}
