ASM: Added code to assembler into a binary and fixed some disassembly logic
This commit is contained in:
parent
3ff187824c
commit
bd84eb5b2e
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
*.o
|
*.o
|
||||||
first
|
first
|
||||||
|
test.rom
|
||||||
|
7
Makefile
7
Makefile
@ -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
|
||||||
|
157
assembly.c
157
assembly.c
@ -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);
|
||||||
|
}
|
||||||
|
15
assembly.h
15
assembly.h
@ -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);
|
||||||
|
71
main.c
71
main.c
@ -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,30 +67,75 @@ 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");
|
||||||
|
|
||||||
|
struct simdata_t *simdata = init_simdata();
|
||||||
|
|
||||||
|
if ( assemble != NULL ){
|
||||||
|
/* RUN ASSEMBLER */
|
||||||
|
struct assembler_context_t *assembler_context=malloc(sizeof(struct assembler_context_t));
|
||||||
|
|
||||||
|
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);
|
||||||
|
}else{
|
||||||
|
/* RUN SIMULATOR */
|
||||||
if (rom == NULL) {
|
if (rom == NULL) {
|
||||||
printf("ERROR: Couldn't open rom file\n");
|
printf("ERROR: Couldn't open rom file\n");
|
||||||
perror(infile);
|
perror(infile);
|
||||||
|
fclose(rom);
|
||||||
|
free_simdata(simdata);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fseek(rom, 0, SEEK_END);
|
fseek(rom, 0, SEEK_END);
|
||||||
if(ftell(rom)!=16777216){
|
if(ftell(rom)!=ADDR_SIZE){
|
||||||
printf("ERROR: ROM file isn't 16MiB\n");
|
printf("ERROR: ROM file isn't 16MiB\n");
|
||||||
|
fclose(rom);
|
||||||
|
free_simdata(simdata);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
fseek(rom, 0, SEEK_SET);
|
fseek(rom, 0, SEEK_SET);
|
||||||
|
|
||||||
struct simdata_t *simdata = init_simdata();
|
|
||||||
if(!simdata){
|
if(!simdata){
|
||||||
gui_error("failed to initialise simdata");
|
gui_error("failed to initialise simdata");
|
||||||
|
fclose(rom);
|
||||||
|
free_simdata(simdata);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(fread(simdata->RAM, 16777216, 1, rom)==0){
|
if(fread(simdata->RAM, ADDR_SIZE, 1, rom)==0){
|
||||||
printf("ERROR: failed to read input file\n");
|
printf("ERROR: failed to read input file\n");
|
||||||
free_simdata(simdata);
|
free_simdata(simdata);
|
||||||
|
fclose(rom);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
fclose(rom);
|
fclose(rom);
|
||||||
@ -104,5 +164,6 @@ int main(int argc, char* argd[] ){
|
|||||||
}
|
}
|
||||||
|
|
||||||
free_simdata(simdata);
|
free_simdata(simdata);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user