ASM: Added code to assembler into a binary and fixed some disassembly logic

This commit is contained in:
(Tim) Efthimis Kritikos 2024-02-03 18:03:37 +00:00
parent 3ff187824c
commit bd84eb5b2e
6 changed files with 289 additions and 49 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
*.o *.o
first first
test.rom

View File

@ -7,16 +7,23 @@ OBJECT_FILES=gui.o main.o simdata.o assembly.o
ifeq "${QUIET}" "1" ifeq "${QUIET}" "1"
QUIET_CC = @echo ' CC '$@; QUIET_CC = @echo ' CC '$@;
QUIET_LINK = @echo ' LINK '$@; QUIET_LINK = @echo ' LINK '$@;
QUIET_FAS = @echo ' FAS '$@;
QUIET_CLEAN = @echo ' CLEAN .'; QUIET_CLEAN = @echo ' CLEAN .';
Q = @ Q = @
else else
Q = Q =
endif endif
all:test.rom
first: ${OBJECT_FILES} first: ${OBJECT_FILES}
${QUIET_LINK} ${QUIET_LINK}
${Q}gcc -ggdb $^ -fsanitize=address -lncurses -ltinfo -o $@ ${Q}gcc -ggdb $^ -fsanitize=address -lncurses -ltinfo -o $@
%.rom:%.asm first
$(QUIET_FAS)
${Q}./first -i test.asm -a test.rom
%.o:%.c %.o:%.c
${QUIET_CC} ${QUIET_CC}
${Q} gcc -ggdb -c $< -Wall -Wextra -Werror -fsanitize=address ${Q} gcc -ggdb -c $< -Wall -Wextra -Werror -fsanitize=address

View File

@ -13,6 +13,10 @@
// +===================================================+ // +===================================================+
// //
// //
// Exception:
// The bytecode 0xFFFFFFFx is an invalid command
// where x is any nibble
//
// //
// INSTRUCTION FORMAT 0: // INSTRUCTION FORMAT 0:
// +===================================================+ // +===================================================+
@ -110,11 +114,11 @@ char *disassemble(uint32_t opcode_be){
break; break;
case 0x02: case 0x02:
case 0x03: case 0x03:
snprintf(ret,MAX_INSTRUCTION_LENGTH,"JMP %s,$%06X",opcode_num&1?"Z":"NZ",val); snprintf(ret,MAX_INSTRUCTION_LENGTH,"JMP,%s $%06X",opcode_num&1?"NZ":"Z",val);
break; break;
case 0x04: case 0x04:
case 0x05: case 0x05:
snprintf(ret,MAX_INSTRUCTION_LENGTH,"JMP %s,$%06X",opcode_num&1?"C":"NC",val); snprintf(ret,MAX_INSTRUCTION_LENGTH,"JMP,%s $%06X",opcode_num&1?"NC":"C",val);
break; break;
default: default:
snprintf(ret,MAX_INSTRUCTION_LENGTH,"UNRECOGNISED INSTR"); snprintf(ret,MAX_INSTRUCTION_LENGTH,"UNRECOGNISED INSTR");
@ -148,7 +152,7 @@ char *disassemble(uint32_t opcode_be){
} }
}else if(instruction_format==2){ }else if(instruction_format==2){
// 16bit opcode // 16bit opcode
opcode_num=(opcode&0x1FFF0000)>>16; opcode_num=(opcode&0x1F000000)>>24;
val1=(opcode&0x00FF0000)>>16; val1=(opcode&0x00FF0000)>>16;
val=opcode&0x0000FFFF; val=opcode&0x0000FFFF;
@ -168,3 +172,150 @@ char *disassemble(uint32_t opcode_be){
return ret; return ret;
} }
uint32_t assemble_line(char *line, __attribute__((unused)) struct assembler_context_t *assembler_context){
uint16_t opcode;
int x;
if(strncmp(line,"JMP",3)==0){
x=3;
if(line[x]==' '){
opcode=0x01;
}else if(line[x]==','){
x++;
if(line[x]=='Z'){
opcode=0x02;
x++;
}else if(line[x]=='C'){
opcode=0x04;
x++;
}else if(line[x]=='N'){
x++;
if(line[x]=='Z'){
opcode=0x03;
x++;
}else if(line[x]=='C'){
opcode=0x05;
x++;
}else
return 0xFFFFFFFF;
}else
return 0xFFFFFFFF;
}else
return 0xFFFFFFFF;
while(line[x]==' ')x++;
uint32_t addr;
if(line[x]=='$'){
x++;
if(sscanf(line+x,"%06X",&addr)!=1)
return 0xFFFFFFFF;
else
return opcode<<24|(addr&0x00FFFFFF);
}else
return 0xFFFFFFFF;
}else{
uint8_t r1,r0,params;
if(strncmp(line,"ADD",3)==0){
x=3;
opcode=0x2000;
params=2;
}else if(strncmp(line,"SUB",3)==0){
x=3;
opcode=0x2001;
params=2;
}else if(strncmp(line,"SL",2)==0){
x=2;
opcode=0x2002;
params=1;
}else if(strncmp(line,"SR",2)==0){
x=2;
opcode=0x2003;
params=1;
}else if(strncmp(line,"CMP",3)==0){
x=3;
opcode=0x2004;
params=2;
}else
params=0;
if(params!=0){
while(line[x]==' ')x++;
if(line[x]=='%'){
x++;
if(line[x]=='R'){
x++;
if(line[x]>='0'&&line[x]<='7'){
r0=line[x]-'0';
if(params==2){
x++;
while(line[x]==' ')x++;
if(line[x]==','){
x++;
while(line[x]==' ')x++;
if(line[x]=='%'){
x++;
if(line[x]=='R'){
x++;
if(line[x]>='0'&&line[x]<='7'){
r1=line[x]-'0';
return (opcode<<16)|r0<<8|r1;
}else
return 0xFFFFFFFF;
}else
return 0xFFFFFFFF;
}else
return 0xFFFFFFFF;
}else
return 0xFFFFFFFF;
}else
return (opcode<<16)|r0<<8;
}else
return 0xFFFFFFFF;
}else
return 0xFFFFFFFF;
}else
return 0xFFFFFFFF;
}else if(strncmp(line,"MOV",3)==0){
uint32_t data;
x=3;
while(line[x]==' ')x++;
if(line[x]=='$'){
x++;
if(sscanf(line+x,"%04X",&data)==1){
x+=4;
while(line[x]==' ')x++;
if(line[x]==','){
x++;
while(line[x]==' ')x++;
if(line[x]=='%'){
x++;
if(line[x]=='R'){
x++;
if(line[x]>='0'&&line[x]<='7'){
r1=line[x]-'0';
x++;
if(line[x]=='l')
return 0x40000000|r1<<16|data;
else if(line[x]=='h')
return 0x41000000|r1<<16|data;
else
return 0xFFFFFFFF;
}else
return 0xFFFFFFFF;
}else
return 0xFFFFFFFF;
}else
return 0xFFFFFFFF;
}else
return 0xFFFFFFFF;
}else
return 0xFFFFFFFF;
}else
return 0xFFFFFFFF;
}else
return 0xFFFFFFFF;
}
}
void free_assembler_context(struct assembler_context_t *tofree){
free(tofree);
}

View File

@ -1,3 +1,16 @@
#include "stdint.h" #include <stdint.h>
char* disassemble(uint32_t opcode); char* disassemble(uint32_t opcode);
struct label_ll_t{
char* name;
uint32_t address;
struct label_ll_t *next;
};
struct assembler_context_t{
struct label_ll_t label_ll;
};
uint32_t assemble_line(char *line, __attribute__((unused)) struct assembler_context_t *assembler_context);
void free_assembler_context(struct assembler_context_t *tofree);

151
main.c
View File

@ -23,16 +23,28 @@
#include "simdata.h" #include "simdata.h"
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
#include "assembly.h"
void help(char* progname){ void help(char* progname){
printf("Usage: %s -i <file> \n", progname); printf("Usage: %s -i <file> \n", progname);
} }
#define ADDR_SIZE 16777216
int dump_rom(char* filename, struct simdata_t *simdata){
FILE* outfile=fopen(filename,"w");
for(int i=0;i<ADDR_SIZE;i++)
fputc(*(simdata->RAM+i),outfile);
fclose(outfile);
return 0;
}
int main(int argc, char* argd[] ){ int main(int argc, char* argd[] ){
/// PARSE COMMAND LINE /// /// PARSE COMMAND LINE ///
char *infile = NULL; char *infile = NULL;
char *assemble = NULL;
int opt; int opt;
while ((opt = getopt(argc, argd, "hi:")) != -1) { while ((opt = getopt(argc, argd, "hi:a:")) != -1) {
switch (opt) { switch (opt) {
case 'h': case 'h':
help(argd[0]); help(argd[0]);
@ -41,6 +53,9 @@ int main(int argc, char* argd[] ){
case 'i': case 'i':
infile=optarg; infile=optarg;
break; break;
case 'a':
assemble=optarg;
break;
default: default:
help(argd[0]); help(argd[0]);
return 1; return 1;
@ -52,57 +67,103 @@ int main(int argc, char* argd[] ){
return 1; return 1;
} }
/// READ ROM FILE /// /// READ INPUT FILE ///
FILE* rom=fopen(infile,"r"); FILE* rom=fopen(infile,"r");
if (rom == NULL) {
printf("ERROR: Couldn't open rom file\n");
perror(infile);
return 1;
}
fseek(rom, 0, SEEK_END);
if(ftell(rom)!=16777216){
printf("ERROR: ROM file isn't 16MiB\n");
return 1;
}
fseek(rom, 0, SEEK_SET);
struct simdata_t *simdata = init_simdata(); struct simdata_t *simdata = init_simdata();
if(!simdata){
gui_error("failed to initialise simdata"); if ( assemble != NULL ){
return 1; /* RUN ASSEMBLER */
} struct assembler_context_t *assembler_context=malloc(sizeof(struct assembler_context_t));
if(fread(simdata->RAM, 16777216, 1, rom)==0){
printf("ERROR: failed to read input file\n"); for (int i=0;i<ADDR_SIZE;i++)
simdata->RAM[i]=0;
int linec=0;
if (rom != NULL) {
char line [1000];
uint32_t opcode;
uint32_t addr=0;
while(fgets(line,sizeof(line),rom)!= NULL){
opcode=assemble_line(line,assembler_context);
if(opcode>0xFFFFFFF1){
printf("Error assembling %s:%d\n", infile,linec+1);
fclose(rom);
free_assembler_context(assembler_context);
free_simdata(simdata);
return 1;
}else{
simdata->RAM[addr]=(0xFF000000&opcode)>>24;
addr++;
simdata->RAM[addr]=(0xFF0000&opcode)>>16;
addr++;
simdata->RAM[addr]=(0xFF00&opcode)>>8;
addr++;
simdata->RAM[addr]=(0xFF&opcode);
addr++;
}
linec++;
}
}
free_assembler_context(assembler_context);
dump_rom(assemble,simdata);
free_simdata(simdata); free_simdata(simdata);
return 1; }else{
} /* RUN SIMULATOR */
fclose(rom); if (rom == NULL) {
printf("ERROR: Couldn't open rom file\n");
perror(infile);
fclose(rom);
free_simdata(simdata);
return 1;
}
fseek(rom, 0, SEEK_END);
if(ftell(rom)!=ADDR_SIZE){
printf("ERROR: ROM file isn't 16MiB\n");
fclose(rom);
free_simdata(simdata);
return 1;
}
fseek(rom, 0, SEEK_SET);
if(!simdata){
gui_error("failed to initialise simdata");
fclose(rom);
free_simdata(simdata);
return 1;
}
if(fread(simdata->RAM, ADDR_SIZE, 1, rom)==0){
printf("ERROR: failed to read input file\n");
free_simdata(simdata);
fclose(rom);
return 1;
}
fclose(rom);
/// INITIALISE GUI /// /// INITIALISE GUI ///
if(start_gui()){ if(start_gui()){
printf("Failed on start_gui()\n"); printf("Failed on start_gui()\n");
free_simdata(simdata);
return 1;
}
update_gui(simdata);
if(gui_continue_request()){
end_gui();
printf("Failed on gui_continue_request()\n");
free_simdata(simdata);
return 1;
}
if(end_gui()){
printf("Failed on end_gui()\n");
free_simdata(simdata);
return 1;
}
free_simdata(simdata); free_simdata(simdata);
return 1;
} }
update_gui(simdata);
if(gui_continue_request()){
end_gui();
printf("Failed on gui_continue_request()\n");
free_simdata(simdata);
return 1;
}
if(end_gui()){
printf("Failed on end_gui()\n");
free_simdata(simdata);
return 1;
}
free_simdata(simdata);
return 0; return 0;
} }

7
test.asm Normal file
View File

@ -0,0 +1,7 @@
JMP $ABCDEF
JMP,NZ $DEADBA
JMP,C $EEEEEF
SL %R7
CMP %R2,%R0
MOV $1238,%R5h
MOV $8321,%R2l