diff --git a/assembly.c b/assembly.c index 9147790..982f39f 100644 --- a/assembly.c +++ b/assembly.c @@ -1,17 +1,170 @@ #include "assembly.h" #include #include +#include // Max instruction width is 25 characters without the null char +// +// INSTRUCTIONS: +// BYTE 3 BYTE 2 BYTE 1 BYTE 0 +// +===================================================+ +// | | | | | +// +===================================================+ +// +// +// +// INSTRUCTION FORMAT 0: +// +===================================================+ +// | OPCODE | 24 BIT IMMEDIATE ADDRESS | +// +===================================================+ +// +// INSTRUCTION FORMAT 1: +// +===================================================+ +// | OPCODE | SOURCE REG | DEST REG | +// +===================================================+ +// +// INSTRUCTION FORMAT 2: +// +===================================================+ +// | OPCODE | DEST REG | 16 BIT IMMEDIATE | +// +===================================================+ +// +// +// +// OPCODE FORMAT: +// ______________________________________________________________________________________________________ +// |BIT | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | +// +----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ +// | | INSTR. FORMAT | 8bit opcode num : 16bit opcode num | +// +----+-----------------+-----------------------------+-----------------------------------------------+ +// +// +// INSTRUCTION FORMAT 0 OPCODE NUM: +// +-------+----------------------------------+--------------+ +// | NUM | DESCRIPTION | AFFECT FLAGS | +// +-------+----------------------------------+--------------+ +// | 5'd0 | NOP | NO | +// +-------+----------------------------------+--------------+ +// | 5'd1 | Unconditional Jump | NO | +// +-------+----------------------------------+--------------+ +// | 5'd2 | Jump if zero flag is set | NO | +// +-------+----------------------------------+--------------+ +// | 5'd3 | Jump if zero flag is not set | NO | +// +-------+----------------------------------+--------------+ +// | 5'd4 | Jump if carry flag is set | NO | +// +-------+----------------------------------+--------------+ +// | 5'd5 | Jump if carry flag is not set | NO | +// +// +// INSTRUCTION FORMAT 1 OPCODE NUM: +// +-------+----------------------------------+--------------+ +// | NUM | DESCRIPTION | AFFECT FLAGS | +// +-------+----------------------------------+--------------+ +// | 13'd0 | ADD | YES | +// +-------+----------------------------------+--------------| +// | 13'd1 | SUBTRACT | YES | +// +-------+----------------------------------+--------------| +// | 13'd2 | SHIFT LEFT | YES | +// +-------+----------------------------------+--------------| +// | 13'd3 | SHIFT RIGHT | YES | +// +-------+----------------------------------+--------------| +// | 13'd4 | COMPARE (SUBTRACT WITHOUT SAVE) | YES | +// +// +// INSTRUCTION FORMAT 2 OPCODE NUM: +// +-------+----------------------------------------------+--------------+ +// | NUM | DESCRIPTION | AFFECT FLAGS | +// +-------+----------------------------------------------+--------------+ +// | 5'd0 | MOV IMMEDIATE TO DEST LOW PART OF REGISTER | NO | +// +-------+----------------------------------------------+--------------+ +// | 5'd1 | MOV IMMEDIATE TO DEST HIGH PART OF REGISTER | NO | + +#define MAX_INSTRUCTION_LENGTH 26 + +char *disassemble(uint32_t opcode_be){ + uint32_t opcode=(opcode_be&0x000000FF)<<24|(opcode_be&0x0000FF00)<<8|(opcode_be&0x00FF0000)>>8|(opcode_be&0xFF000000)>>24; + char *ret=malloc(MAX_INSTRUCTION_LENGTH); -char *disassemble(uint32_t opcode){ - char *ret=malloc(26); if (!ret) return NULL; - if(opcode!=0x01ABCDEF) - memcpy(ret,"placeholder",12); - else - memcpy(ret,"easter egg",11); + + //////// PARSE BITECODE ////////// + + int instruction_format,opcode_num; + uint32_t val; + uint8_t val1; + uint8_t val2; + + instruction_format=(opcode&0xE0000000)>>29; + if(instruction_format==0){ + // 8bit opcode + opcode_num=(opcode&0x1F000000)>>24; + val=opcode&0x00FFFFFF; + + switch(opcode_num){ + case 0x00: + snprintf(ret,MAX_INSTRUCTION_LENGTH,"NOP"); + break; + case 0x01: + snprintf(ret,MAX_INSTRUCTION_LENGTH,"JMP $%06X",val); + break; + case 0x02: + case 0x03: + snprintf(ret,MAX_INSTRUCTION_LENGTH,"JMP %s,$%06X",opcode_num&1?"Z":"NZ",val); + break; + case 0x04: + case 0x05: + snprintf(ret,MAX_INSTRUCTION_LENGTH,"JMP %s,$%06X",opcode_num&1?"C":"NC",val); + break; + default: + snprintf(ret,MAX_INSTRUCTION_LENGTH,"UNRECOGNISED INSTR"); + break; + } + }else if(instruction_format==1){ + // 16bit opcode + opcode_num=(opcode&0x1FFF0000)>>16; + val1=(opcode&0x0000FF00)>>8; + val2=opcode&0x000000FF; + + switch(opcode_num){ + case 0x00: + snprintf(ret,MAX_INSTRUCTION_LENGTH,"ADD %%R%0d, %%R%0d",val1,val2); + break; + case 0x01: + snprintf(ret,MAX_INSTRUCTION_LENGTH,"SUB %%R%0d, %%R%0d",val1,val2); + break; + case 0x02: + snprintf(ret,MAX_INSTRUCTION_LENGTH,"SL %%R%0d",val1); + break; + case 0x03: + snprintf(ret,MAX_INSTRUCTION_LENGTH,"SR %%R%0d",val1); + break; + case 0x04: + snprintf(ret,MAX_INSTRUCTION_LENGTH,"CMP %%R%0d, %%R%0d",val1,val2); + break; + default: + snprintf(ret,MAX_INSTRUCTION_LENGTH,"UNRECOGNISED INSTRUCTION"); + break; + } + }else if(instruction_format==2){ + // 16bit opcode + opcode_num=(opcode&0x1FFF0000)>>16; + val1=(opcode&0x00FF0000)>>16; + val=opcode&0x0000FFFF; + + switch(opcode_num){ + case 0x00: + snprintf(ret,MAX_INSTRUCTION_LENGTH,"MOV $%04X, %%R%0dl",val,val1); + break; + case 0x01: + snprintf(ret,MAX_INSTRUCTION_LENGTH,"MOV $%04X, %%R%0dh",val,val1); + break; + default: + snprintf(ret,MAX_INSTRUCTION_LENGTH,"UNRECOGNISED INSTRUCTION"); + break; + } + }else + snprintf(ret,MAX_INSTRUCTION_LENGTH,"UNRECOGNISED INSTRUCTION"); + return ret; } diff --git a/gui.c b/gui.c index d621fa0..0b9a95b 100644 --- a/gui.c +++ b/gui.c @@ -182,7 +182,7 @@ int update_general_disas(struct simdata_t *simdata){ if(width<18){ mvwprintw(general_disas,1,1,"too small window"); }else{ - uint32_t ADDRESS=(simdata->PC-(height/2-2)*3)&0x00FFFFFF; + uint32_t ADDRESS=(simdata->PC-(height/2-2)*4)&0x00FFFFFF; for (int i=2;iPC) wattroff(general_disas,A_BOLD); - ADDRESS=(ADDRESS+3)&0xFFFFFF; + ADDRESS=(ADDRESS+4)&0xFFFFFF; free(disas); } mvwaddch(general_disas,height/2,offset_arrow,ACS_RARROW);