2024-10-30 11:29:20 +08:00
|
|
|
/***************************************************************************
|
|
|
|
|
* file name : asm_parser.c *
|
|
|
|
|
* author : *
|
|
|
|
|
* description : the functions are declared in asm_parser.h *
|
|
|
|
|
* The intention of this library is to parse a .ASM file *
|
|
|
|
|
* *
|
|
|
|
|
* *
|
|
|
|
|
***************************************************************************
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include "asm_parser.h"
|
|
|
|
|
|
2024-10-30 16:31:10 +08:00
|
|
|
int read_asm_file(char *filename, char program[ROWS][COLS]) {
|
|
|
|
|
FILE *file = fopen(filename, "r");
|
|
|
|
|
if (!file) {
|
2024-10-30 17:34:54 +08:00
|
|
|
printf("error: read_asm_file failed\n");
|
|
|
|
|
return 2;
|
2024-10-30 16:31:10 +08:00
|
|
|
}
|
|
|
|
|
int line_num = 0;
|
|
|
|
|
while (fgets(program[line_num], COLS, file) != NULL && line_num < ROWS) {
|
|
|
|
|
// Remove trailing newline
|
|
|
|
|
size_t len = strlen(program[line_num]);
|
|
|
|
|
if (len > 0 && program[line_num][len - 1] == '\n') {
|
|
|
|
|
program[line_num][len - 1] = '\0';
|
|
|
|
|
len--;
|
|
|
|
|
}
|
|
|
|
|
// Remove comments starting with ';' or '#'
|
|
|
|
|
char *comment = strchr(program[line_num], ';');
|
|
|
|
|
if (comment != NULL) {
|
|
|
|
|
*comment = '\0';
|
|
|
|
|
len = comment - program[line_num];
|
|
|
|
|
}
|
|
|
|
|
comment = strchr(program[line_num], '#');
|
|
|
|
|
if (comment != NULL) {
|
|
|
|
|
*comment = '\0';
|
|
|
|
|
len = comment - program[line_num];
|
|
|
|
|
}
|
|
|
|
|
// Trim trailing whitespace
|
|
|
|
|
while (len > 0 && isspace(program[line_num][len - 1])) {
|
|
|
|
|
program[line_num][--len] = '\0';
|
|
|
|
|
}
|
|
|
|
|
// Skip empty lines
|
|
|
|
|
if (len == 0) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
line_num++;
|
|
|
|
|
}
|
|
|
|
|
fclose(file);
|
2024-10-30 17:34:54 +08:00
|
|
|
return 0;
|
2024-10-30 16:31:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int parse_instruction(char *instr, char *instr_bin_str) {
|
|
|
|
|
// Remove leading whitespace
|
|
|
|
|
while (isspace(*instr)) instr++;
|
|
|
|
|
if (*instr == '\0') {
|
|
|
|
|
// Empty line
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
// Tokenize the instruction
|
|
|
|
|
char instr_copy[COLS];
|
|
|
|
|
strcpy(instr_copy, instr);
|
|
|
|
|
char *token = strtok(instr_copy, " ,\t");
|
|
|
|
|
if (token == NULL) {
|
|
|
|
|
// Empty or invalid instruction
|
2024-10-30 17:34:54 +08:00
|
|
|
printf("error: parse_instruction failed\n");
|
|
|
|
|
return 3;
|
2024-10-30 16:31:10 +08:00
|
|
|
}
|
|
|
|
|
to_uppercase(token);
|
|
|
|
|
if (strcmp(token, "ADD") == 0) {
|
|
|
|
|
return parse_add(instr, instr_bin_str);
|
|
|
|
|
} else if (strcmp(token, "MUL") == 0) {
|
|
|
|
|
return parse_mul(instr, instr_bin_str);
|
|
|
|
|
} else if (strcmp(token, "SUB") == 0) {
|
|
|
|
|
return parse_sub(instr, instr_bin_str);
|
|
|
|
|
} else if (strcmp(token, "DIV") == 0) {
|
|
|
|
|
return parse_div(instr, instr_bin_str);
|
|
|
|
|
} else if (strcmp(token, "AND") == 0) {
|
|
|
|
|
return parse_and(instr, instr_bin_str);
|
|
|
|
|
} else if (strcmp(token, "OR") == 0) {
|
|
|
|
|
return parse_or(instr, instr_bin_str);
|
|
|
|
|
} else if (strcmp(token, "XOR") == 0) {
|
|
|
|
|
return parse_xor(instr, instr_bin_str);
|
|
|
|
|
}
|
|
|
|
|
// Add other instructions here
|
|
|
|
|
else {
|
2024-10-30 17:34:54 +08:00
|
|
|
printf("error: parse_instruction failed\n");
|
|
|
|
|
return 3;
|
2024-10-30 16:31:10 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-30 17:34:54 +08:00
|
|
|
int parse_reg(char reg_num, char *instr_bin_str) {
|
|
|
|
|
if (reg_num < '0' || reg_num > '7') {
|
|
|
|
|
printf("error: parse_reg failed\n");
|
|
|
|
|
return 5;
|
2024-10-30 16:31:10 +08:00
|
|
|
}
|
2024-10-30 17:34:54 +08:00
|
|
|
int reg = reg_num - '0';
|
|
|
|
|
char bin_str[4];
|
|
|
|
|
int_to_bin_str(reg, 3, bin_str);
|
|
|
|
|
strcat(instr_bin_str, bin_str);
|
|
|
|
|
return 0;
|
2024-10-30 16:31:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void int_to_bin_str(int num, int bits, char *bin_str) {
|
|
|
|
|
bin_str[bits] = '\0';
|
|
|
|
|
for (int i = bits - 1; i >= 0; i--) {
|
|
|
|
|
bin_str[i] = (num % 2) + '0';
|
|
|
|
|
num /= 2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void to_uppercase(char *str) {
|
|
|
|
|
for (; *str; ++str) {
|
|
|
|
|
*str = toupper(*str);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int parse_add(char *instr, char *instr_bin_str) {
|
|
|
|
|
// Instruction format: ADD Rd, Rs, Rt
|
|
|
|
|
// Opcode: 0001
|
2024-10-30 17:34:54 +08:00
|
|
|
strcpy(instr_bin_str, "0001"); // Opcode
|
2024-10-30 16:31:10 +08:00
|
|
|
// Tokenize the instruction to get registers
|
|
|
|
|
char instr_copy[COLS];
|
|
|
|
|
strcpy(instr_copy, instr);
|
|
|
|
|
char *token = strtok(instr_copy, " ,\t"); // Skip 'ADD'
|
|
|
|
|
token = strtok(NULL, " ,\t"); // Rd
|
2024-10-30 17:34:54 +08:00
|
|
|
if (token == NULL) {
|
|
|
|
|
printf("error: parse_add() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
char rd_num = token[1]; // Assuming 'R' is at token[0]
|
|
|
|
|
int ret = parse_reg(rd_num, instr_bin_str); // Rd
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
printf("error: parse_add() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
2024-10-30 16:31:10 +08:00
|
|
|
token = strtok(NULL, " ,\t"); // Rs
|
2024-10-30 17:34:54 +08:00
|
|
|
if (token == NULL) {
|
|
|
|
|
printf("error: parse_add() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
char rs_num = token[1];
|
|
|
|
|
ret = parse_reg(rs_num, instr_bin_str); // Rs
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
printf("error: parse_add() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
strcat(instr_bin_str, "000"); // Sub-opcode for ADD
|
2024-10-30 16:31:10 +08:00
|
|
|
token = strtok(NULL, " ,\t"); // Rt
|
2024-10-30 17:34:54 +08:00
|
|
|
if (token == NULL) {
|
|
|
|
|
printf("error: parse_add() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
char rt_num = token[1];
|
|
|
|
|
ret = parse_reg(rt_num, instr_bin_str); // Rt
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
printf("error: parse_add() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
2024-10-30 16:31:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int parse_mul(char *instr, char *instr_bin_str) {
|
|
|
|
|
// Instruction format: MUL Rd, Rs, Rt
|
|
|
|
|
// Opcode: 0001
|
2024-10-30 17:34:54 +08:00
|
|
|
strcpy(instr_bin_str, "0001"); // Opcode
|
2024-10-30 16:31:10 +08:00
|
|
|
// Tokenize the instruction to get registers
|
|
|
|
|
char instr_copy[COLS];
|
|
|
|
|
strcpy(instr_copy, instr);
|
|
|
|
|
char *token = strtok(instr_copy, " ,\t"); // Skip 'MUL'
|
|
|
|
|
token = strtok(NULL, " ,\t"); // Rd
|
2024-10-30 17:34:54 +08:00
|
|
|
if (token == NULL) {
|
|
|
|
|
printf("error: parse_mul() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
char rd_num = token[1];
|
|
|
|
|
int ret = parse_reg(rd_num, instr_bin_str); // Rd
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
printf("error: parse_mul() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
2024-10-30 16:31:10 +08:00
|
|
|
token = strtok(NULL, " ,\t"); // Rs
|
2024-10-30 17:34:54 +08:00
|
|
|
if (token == NULL) {
|
|
|
|
|
printf("error: parse_mul() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
char rs_num = token[1];
|
|
|
|
|
ret = parse_reg(rs_num, instr_bin_str); // Rs
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
printf("error: parse_mul() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
strcat(instr_bin_str, "001"); // Sub-opcode for MUL
|
2024-10-30 16:31:10 +08:00
|
|
|
token = strtok(NULL, " ,\t"); // Rt
|
2024-10-30 17:34:54 +08:00
|
|
|
if (token == NULL) {
|
|
|
|
|
printf("error: parse_mul() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
char rt_num = token[1];
|
|
|
|
|
ret = parse_reg(rt_num, instr_bin_str); // Rt
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
printf("error: parse_mul() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
2024-10-30 16:31:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int parse_sub(char *instr, char *instr_bin_str) {
|
2024-10-30 17:34:54 +08:00
|
|
|
// Similar to parse_add, with sub-opcode '010'
|
|
|
|
|
strcpy(instr_bin_str, "0001"); // Opcode
|
2024-10-30 16:31:10 +08:00
|
|
|
char instr_copy[COLS];
|
|
|
|
|
strcpy(instr_copy, instr);
|
|
|
|
|
char *token = strtok(instr_copy, " ,\t"); // Skip 'SUB'
|
|
|
|
|
token = strtok(NULL, " ,\t"); // Rd
|
2024-10-30 17:34:54 +08:00
|
|
|
if (token == NULL) {
|
|
|
|
|
printf("error: parse_sub() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
char rd_num = token[1];
|
|
|
|
|
int ret = parse_reg(rd_num, instr_bin_str); // Rd
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
printf("error: parse_sub() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
2024-10-30 16:31:10 +08:00
|
|
|
token = strtok(NULL, " ,\t"); // Rs
|
2024-10-30 17:34:54 +08:00
|
|
|
if (token == NULL) {
|
|
|
|
|
printf("error: parse_sub() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
char rs_num = token[1];
|
|
|
|
|
ret = parse_reg(rs_num, instr_bin_str); // Rs
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
printf("error: parse_sub() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
strcat(instr_bin_str, "010"); // Sub-opcode for SUB
|
2024-10-30 16:31:10 +08:00
|
|
|
token = strtok(NULL, " ,\t"); // Rt
|
2024-10-30 17:34:54 +08:00
|
|
|
if (token == NULL) {
|
|
|
|
|
printf("error: parse_sub() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
char rt_num = token[1];
|
|
|
|
|
ret = parse_reg(rt_num, instr_bin_str); // Rt
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
printf("error: parse_sub() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
2024-10-30 16:31:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int parse_div(char *instr, char *instr_bin_str) {
|
2024-10-30 17:34:54 +08:00
|
|
|
// Similar to parse_add, with sub-opcode '011'
|
|
|
|
|
strcpy(instr_bin_str, "0001"); // Opcode
|
2024-10-30 16:31:10 +08:00
|
|
|
char instr_copy[COLS];
|
|
|
|
|
strcpy(instr_copy, instr);
|
|
|
|
|
char *token = strtok(instr_copy, " ,\t"); // Skip 'DIV'
|
|
|
|
|
token = strtok(NULL, " ,\t"); // Rd
|
2024-10-30 17:34:54 +08:00
|
|
|
if (token == NULL) {
|
|
|
|
|
printf("error: parse_div() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
char rd_num = token[1];
|
|
|
|
|
int ret = parse_reg(rd_num, instr_bin_str); // Rd
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
printf("error: parse_div() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
2024-10-30 16:31:10 +08:00
|
|
|
token = strtok(NULL, " ,\t"); // Rs
|
2024-10-30 17:34:54 +08:00
|
|
|
if (token == NULL) {
|
|
|
|
|
printf("error: parse_div() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
char rs_num = token[1];
|
|
|
|
|
ret = parse_reg(rs_num, instr_bin_str); // Rs
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
printf("error: parse_div() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
strcat(instr_bin_str, "011"); // Sub-opcode for DIV
|
2024-10-30 16:31:10 +08:00
|
|
|
token = strtok(NULL, " ,\t"); // Rt
|
2024-10-30 17:34:54 +08:00
|
|
|
if (token == NULL) {
|
|
|
|
|
printf("error: parse_div() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
char rt_num = token[1];
|
|
|
|
|
ret = parse_reg(rt_num, instr_bin_str); // Rt
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
printf("error: parse_div() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
2024-10-30 16:31:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int parse_and(char *instr, char *instr_bin_str) {
|
2024-10-30 17:34:54 +08:00
|
|
|
// Opcode: 0101, sub-opcode '000'
|
|
|
|
|
strcpy(instr_bin_str, "0101"); // Opcode
|
2024-10-30 16:31:10 +08:00
|
|
|
char instr_copy[COLS];
|
|
|
|
|
strcpy(instr_copy, instr);
|
|
|
|
|
char *token = strtok(instr_copy, " ,\t"); // Skip 'AND'
|
|
|
|
|
token = strtok(NULL, " ,\t"); // Rd
|
2024-10-30 17:34:54 +08:00
|
|
|
if (token == NULL) {
|
|
|
|
|
printf("error: parse_and() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
char rd_num = token[1];
|
|
|
|
|
int ret = parse_reg(rd_num, instr_bin_str); // Rd
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
printf("error: parse_and() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
2024-10-30 16:31:10 +08:00
|
|
|
token = strtok(NULL, " ,\t"); // Rs
|
2024-10-30 17:34:54 +08:00
|
|
|
if (token == NULL) {
|
|
|
|
|
printf("error: parse_and() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
char rs_num = token[1];
|
|
|
|
|
ret = parse_reg(rs_num, instr_bin_str); // Rs
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
printf("error: parse_and() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
strcat(instr_bin_str, "000"); // Sub-opcode for AND
|
2024-10-30 16:31:10 +08:00
|
|
|
token = strtok(NULL, " ,\t"); // Rt
|
2024-10-30 17:34:54 +08:00
|
|
|
if (token == NULL) {
|
|
|
|
|
printf("error: parse_and() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
char rt_num = token[1];
|
|
|
|
|
ret = parse_reg(rt_num, instr_bin_str); // Rt
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
printf("error: parse_and() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
2024-10-30 16:31:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int parse_or(char *instr, char *instr_bin_str) {
|
2024-10-30 17:34:54 +08:00
|
|
|
// Opcode: 0101, sub-opcode '010'
|
|
|
|
|
strcpy(instr_bin_str, "0101"); // Opcode
|
2024-10-30 16:31:10 +08:00
|
|
|
char instr_copy[COLS];
|
|
|
|
|
strcpy(instr_copy, instr);
|
|
|
|
|
char *token = strtok(instr_copy, " ,\t"); // Skip 'OR'
|
|
|
|
|
token = strtok(NULL, " ,\t"); // Rd
|
2024-10-30 17:34:54 +08:00
|
|
|
if (token == NULL) {
|
|
|
|
|
printf("error: parse_or() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
char rd_num = token[1];
|
|
|
|
|
int ret = parse_reg(rd_num, instr_bin_str); // Rd
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
printf("error: parse_or() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
2024-10-30 16:31:10 +08:00
|
|
|
token = strtok(NULL, " ,\t"); // Rs
|
2024-10-30 17:34:54 +08:00
|
|
|
if (token == NULL) {
|
|
|
|
|
printf("error: parse_or() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
char rs_num = token[1];
|
|
|
|
|
ret = parse_reg(rs_num, instr_bin_str); // Rs
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
printf("error: parse_or() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
strcat(instr_bin_str, "010"); // Sub-opcode for OR
|
2024-10-30 16:31:10 +08:00
|
|
|
token = strtok(NULL, " ,\t"); // Rt
|
2024-10-30 17:34:54 +08:00
|
|
|
if (token == NULL) {
|
|
|
|
|
printf("error: parse_or() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
char rt_num = token[1];
|
|
|
|
|
ret = parse_reg(rt_num, instr_bin_str); // Rt
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
printf("error: parse_or() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
2024-10-30 16:31:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int parse_xor(char *instr, char *instr_bin_str) {
|
2024-10-30 17:34:54 +08:00
|
|
|
// Opcode: 0101, sub-opcode '011'
|
|
|
|
|
strcpy(instr_bin_str, "0101"); // Opcode
|
2024-10-30 16:31:10 +08:00
|
|
|
char instr_copy[COLS];
|
|
|
|
|
strcpy(instr_copy, instr);
|
|
|
|
|
char *token = strtok(instr_copy, " ,\t"); // Skip 'XOR'
|
|
|
|
|
token = strtok(NULL, " ,\t"); // Rd
|
2024-10-30 17:34:54 +08:00
|
|
|
if (token == NULL) {
|
|
|
|
|
printf("error: parse_xor() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
char rd_num = token[1];
|
|
|
|
|
int ret = parse_reg(rd_num, instr_bin_str); // Rd
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
printf("error: parse_xor() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
2024-10-30 16:31:10 +08:00
|
|
|
token = strtok(NULL, " ,\t"); // Rs
|
2024-10-30 17:34:54 +08:00
|
|
|
if (token == NULL) {
|
|
|
|
|
printf("error: parse_xor() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
char rs_num = token[1];
|
|
|
|
|
ret = parse_reg(rs_num, instr_bin_str); // Rs
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
printf("error: parse_xor() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
strcat(instr_bin_str, "011"); // Sub-opcode for XOR
|
2024-10-30 16:31:10 +08:00
|
|
|
token = strtok(NULL, " ,\t"); // Rt
|
2024-10-30 17:34:54 +08:00
|
|
|
if (token == NULL) {
|
|
|
|
|
printf("error: parse_xor() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
char rt_num = token[1];
|
|
|
|
|
ret = parse_reg(rt_num, instr_bin_str); // Rt
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
printf("error: parse_xor() failed\n");
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
2024-10-30 16:31:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned short int str_to_bin(char *instr_bin_str) {
|
|
|
|
|
unsigned short int result = 0;
|
|
|
|
|
for (int i = 0; i < 16; i++) {
|
|
|
|
|
result <<= 1;
|
|
|
|
|
if (instr_bin_str[i] == '1') {
|
|
|
|
|
result |= 1;
|
|
|
|
|
} else if (instr_bin_str[i] != '0') {
|
|
|
|
|
// Invalid character
|
2024-10-30 17:34:54 +08:00
|
|
|
printf("error: str_to_bin failed\n");
|
|
|
|
|
return 6;
|
2024-10-30 16:31:10 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int write_obj_file(char *filename, unsigned short int program_bin[ROWS], int instr_count) {
|
|
|
|
|
FILE *file = fopen(filename, "wb");
|
|
|
|
|
if (!file) {
|
2024-10-30 17:34:54 +08:00
|
|
|
printf("error: write_obj_file failed\n");
|
|
|
|
|
return 7;
|
2024-10-30 16:31:10 +08:00
|
|
|
}
|
|
|
|
|
// Write the code header: xCADE, address (start at 0), n (instr_count)
|
|
|
|
|
unsigned short int header[3];
|
|
|
|
|
header[0] = 0xCADE;
|
|
|
|
|
header[1] = 0x0000; // Starting address, assume 0 for now
|
|
|
|
|
header[2] = instr_count;
|
|
|
|
|
fwrite(header, sizeof(unsigned short int), 3, file);
|
|
|
|
|
// Write the instructions
|
|
|
|
|
fwrite(program_bin, sizeof(unsigned short int), instr_count, file);
|
|
|
|
|
fclose(file);
|
|
|
|
|
return 0;
|
2024-10-30 17:34:54 +08:00
|
|
|
}
|