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
|
||||
first
|
||||
test.rom
|
||||
|
7
Makefile
7
Makefile
@ -7,16 +7,23 @@ OBJECT_FILES=gui.o main.o simdata.o assembly.o
|
||||
ifeq "${QUIET}" "1"
|
||||
QUIET_CC = @echo ' CC '$@;
|
||||
QUIET_LINK = @echo ' LINK '$@;
|
||||
QUIET_FAS = @echo ' FAS '$@;
|
||||
QUIET_CLEAN = @echo ' CLEAN .';
|
||||
Q = @
|
||||
else
|
||||
Q =
|
||||
endif
|
||||
|
||||
all:test.rom
|
||||
|
||||
first: ${OBJECT_FILES}
|
||||
${QUIET_LINK}
|
||||
${Q}gcc -ggdb $^ -fsanitize=address -lncurses -ltinfo -o $@
|
||||
|
||||
%.rom:%.asm first
|
||||
$(QUIET_FAS)
|
||||
${Q}./first -i test.asm -a test.rom
|
||||
|
||||
%.o:%.c
|
||||
${QUIET_CC}
|
||||
${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:
|
||||
// +===================================================+
|
||||
@ -110,11 +114,11 @@ char *disassemble(uint32_t opcode_be){
|
||||
break;
|
||||
case 0x02:
|
||||
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;
|
||||
case 0x04:
|
||||
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;
|
||||
default:
|
||||
snprintf(ret,MAX_INSTRUCTION_LENGTH,"UNRECOGNISED INSTR");
|
||||
@ -148,7 +152,7 @@ char *disassemble(uint32_t opcode_be){
|
||||
}
|
||||
}else if(instruction_format==2){
|
||||
// 16bit opcode
|
||||
opcode_num=(opcode&0x1FFF0000)>>16;
|
||||
opcode_num=(opcode&0x1F000000)>>24;
|
||||
val1=(opcode&0x00FF0000)>>16;
|
||||
val=opcode&0x0000FFFF;
|
||||
|
||||
@ -168,3 +172,150 @@ char *disassemble(uint32_t opcode_be){
|
||||
|
||||
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);
|
||||
|
||||
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 <unistd.h>
|
||||
#include <errno.h>
|
||||
#include "assembly.h"
|
||||
|
||||
void help(char* 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[] ){
|
||||
/// PARSE COMMAND LINE ///
|
||||
char *infile = NULL;
|
||||
char *assemble = NULL;
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argd, "hi:")) != -1) {
|
||||
while ((opt = getopt(argc, argd, "hi:a:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'h':
|
||||
help(argd[0]);
|
||||
@ -41,6 +53,9 @@ int main(int argc, char* argd[] ){
|
||||
case 'i':
|
||||
infile=optarg;
|
||||
break;
|
||||
case 'a':
|
||||
assemble=optarg;
|
||||
break;
|
||||
default:
|
||||
help(argd[0]);
|
||||
return 1;
|
||||
@ -52,30 +67,75 @@ int main(int argc, char* argd[] ){
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// READ ROM FILE ///
|
||||
/// READ INPUT FILE ///
|
||||
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) {
|
||||
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)!=16777216){
|
||||
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);
|
||||
|
||||
struct simdata_t *simdata = init_simdata();
|
||||
if(!simdata){
|
||||
gui_error("failed to initialise simdata");
|
||||
fclose(rom);
|
||||
free_simdata(simdata);
|
||||
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");
|
||||
free_simdata(simdata);
|
||||
fclose(rom);
|
||||
return 1;
|
||||
}
|
||||
fclose(rom);
|
||||
@ -104,5 +164,6 @@ int main(int argc, char* argd[] ){
|
||||
}
|
||||
|
||||
free_simdata(simdata);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user