Nesta disciplina os alunos trabalharam com o caminho de dados das intruções de um processador feito pelo professor para o ICMC-USP, conhecendo como cada instrução funciona e até criando uma e adicionando-a à arquitetura: Em nosso projeto, implementamos a instrução POW2, que calcula a potência de 2 do número que estiver no segundo registrador de argumento e guarda o resultado da operação no primeiro registrador de argumento.
Nosso jogo é uma simulação pitoresca de um minigame que muitos alunos frequentadores do bandejão da USP de São Carlos jogam todos os dias: A fuga da ducha do Tatuado do Bandeco. Bricadeiras à parte e com todo respeito ao funcionário exemplar, temos aqui nosso jogo feito na linguagem Assembly do processador do professor Simões.
Nele o jogador (aluno) deve pegar os itens na mesa e entregar no balcão sem se molhar. Tente uma vez! Ande utilizando WASD e tente chegar ao outro lado e voltar sem ser atingido pelas gotas geladas da ducha!
Para jogar você deve ter instalado o simulador disponibilizado pelo professor e, na pasta Simulador, incluir o arquivo .asm que disponibilizamos. Feito isso, abra o simulador com o executável do Sublime e abra o arquivo .asm. Para compilar aperte F7, e, quando a janela do simulador abrir, basta apertar HOME e se divertir!
Como nova instrução implementamos a instrução POW2 que calcula a potência de 2 do segundo argumento da instrução e guarda o resultado no primeiro argumento
loadn r0, #32
loadn r1, #2
loadn r2, #'Q'
POW2 r1,r1
add r2,r2,r1
outchar r2, r0 ; Printa U na linha 32
#define LMOD_CODE 95
#define NOP_CODE 0
#define INPUT_CODE 96
#define OUTPUT_CODE 97
#define POW2_CODE 99 // NOVA INSTRUCAO
/* Aritmethic Instructions(All should begin with "10"): */
#define ADD "100000"
#define SUB "100001"
#define MUL "100010"
#define DIV "100011"
#define INC "100100"
#define LMOD "100101"
#define POW2 "100110"
/*POW2*/
#define POW2_STR "POW2"
// 1) Definir os separadores da Instrucao e quantas linhas do EXE (mif) ela necessita:
/* Instrucoes de 2 argumentos e 1 linha : instr (), () -> [...] */
case NOT_CODE : /* Eu pus aqui pois sera' Rx <- Not Ry */
case MOV_CODE :
case OUTCHAR_CODE :
case CMP_CODE :
case POW2_CODE : // NOVA INSTRUCAO
parser_SkipUntil(',');
parser_SkipUntilEnd();
end_cnt++;
break;
// 2) Explicar como o Montador vai montar os BITs da Instrucao e escrever no arquivo:
/* ==============
POW2 Rx Ry
============== */
case POW2_CODE:
str_tmp1 = parser_GetItem_s();
val1 = BuscaRegistrador(str_tmp1);
free(str_tmp1);
parser_Match(',');
str_tmp2 = parser_GetItem_s();
val2 = BuscaRegistrador(str_tmp2);
free(str_tmp2);
str_tmp1 = ConverteRegistrador(val1);
str_tmp2 = ConverteRegistrador(val2);
sprintf(str_msg, "%s%s%s0000", POW2, str_tmp1, str_tmp2);
free(str_tmp1);
free(str_tmp2);
parser_Write_Inst(str_msg, end_cnt);
end_cnt += 1;
break;
// 3) Buscar o nome da instrucao na base de instrucoes e retornar 'op_code interno' da instrucao:
else if (strcmp(str_tmp, POW2_STR) == 0){
return POW2_CODE;
}
Para compilar, basta usar o gcc cos arquivos da parta Montador:
Para executar o 'montador', passe os seguintes parâmetros:
Dessa forma, o montador gerará o arquivo .mif que será utilizado na placa FPGA ou no simulador.
Os alunos Susy (12694007), Otávio(11767796) e Adalton(12542435) agradecem o empenho do professor Simões e pelos conhecimentos passados para construção da arquitetura.:nerd_face: