diff --git a/docs/document.tex b/docs/document.tex index fc241c5..9bee4f5 100644 --- a/docs/document.tex +++ b/docs/document.tex @@ -82,7 +82,7 @@ 0000 0 & XXX \\ \hline \end{tabular} - \caption{Encoding Layout, Register Required} + \caption{Encoding Layout, No Register Required} \label{fig:NoRegisterEncoding} \end{figure} @@ -92,28 +92,31 @@ or "word" for two bytes. That would make the assembly easier to read but put a bit more work on the assembler. The Stack Pointer will start 2 bytes above the video memory start. \section{COPY (Copy Word from Address)} - \OpcodeTable{0x08}{0000 1000}{copy}{Register}{Address}\\[6pt] + \OpcodeTable{0x08}{0000 1000}{copya}{Register}{Address}\\[6pt] Copy a machine word from Operand 2 into Operand 1. \section{COPY BYTE (Copy Byte from Address)} - \OpcodeTable{0x10}{0001 0000}{copy byte}{Register}{Address}\\[6pt] + \OpcodeTable{0x10}{0001 0000}{copyab}{Register}{Address}\\[6pt] Copy a byte (8 bits) from Operand 2 into Operand 1, clearing the setting the most significant bits to zero. \section{COPY (Copy Word Indirect Address)} - \OpcodeTable{0x18}{0001 1000}{copy}{Register}{[Register]}\\[6pt] + \OpcodeTable{0x18}{0001 1000}{copyra}{Register}{[Register]}\\[6pt] Copy a machine word from the address stored in Operand 2 into Operand 1. \section{COPY BYTE (Copy Byte Indirect Address)} - \OpcodeTable{0x20}{0010 0000}{copy byte}{Register}{[Register]}\\[6pt] + \OpcodeTable{0x20}{0010 0000}{copyrab}{Register}{[Register]}\\[6pt] Copy a byte (8 bits) from the address stored in Operand 2 into Operand 1. \section{COPY (Copy)} - \OpcodeTable{0x28}{0010 1000}{copy}{[Register]}{[Register]}\\[6pt] + \OpcodeTable{0x28}{0010 1000}{copyrara}{[Register]}{[Register]}\\[6pt] Copy a machine word from the address stored in Operand 2 into the address stored in Operand 1. \section{COPY BYTE (Copy Byte)} - \OpcodeTable{0x30}{0011 0000}{copy byte}{[Register]}{[Register]}\\[6pt] + \OpcodeTable{0x30}{0011 0000}{copyrarab}{[Register]}{[Register]}\\[6pt] Copy a byte (8 bits) from the address stored in Operand 2 into the address stored in Operand 1. \section{COPY (Copy)} \OpcodeTable{0x38}{0011 1000}{copy}{Register}{Register}\\[6pt] Copy a machine word from Operand 2 into Operand 1. + \section{COPY (Copy Immediate)} + \OpcodeTable{0xC0}{1100 0000}{copyi}{Register}{Constant}\\[6pt] + Copy a machine word from Operand 2 into Operand 1. \section{COPY BYTE (Copy Byte)} - \OpcodeTable{0x40}{0100 0000}{copy byte}{Register}{Constant}\\[6pt] + \OpcodeTable{0x40}{0100 0000}{copyb}{Register}{Constant}\\[6pt] Copy a byte (8 bits) from Operand 2 into Operand 1. \section{CMP (Compare)} \OpcodeTable{0x48}{0100 1000}{cmp}{Register}{Register}\\[6pt] @@ -128,37 +131,37 @@ \OpcodeTable{0x60}{0110 0000}{sub}{Register}{Register}\\[6pt] Performs subtraction on a register with a value from another (or the same) register. \section{AND (Logical AND)} - \OpcodeTable{0x70}{0111 0000}{and}{Register}{Register}\\[6pt] + \OpcodeTable{0x68}{0110 1000}{and}{Register}{Register}\\[6pt] Logical ANDs the two registers together storing the result in operand 1. \section{XOR (Logical Exclusive OR)} - \OpcodeTable{0x78}{0111 1000}{xor}{Register}{Register}\\[6pt] + \OpcodeTable{0x70}{0111 0000}{xor}{Register}{Register}\\[6pt] Logical XORs the two registers together storing the result in operand 1. \section{OR (Logical OR)} - \OpcodeTable{0x80}{1000 0000}{or}{Register}{Register}\\[6pt] + \OpcodeTable{0x78}{0111 1000}{or}{Register}{Register}\\[6pt] Logical ORs the two registers together storing the result in operand 1. \section{NOT (Logical Negation)} - \OpcodeTable{0x88}{1000 1000}{not}{Register}{None}\\[6pt] + \OpcodeTable{0x80}{1000 0000}{not}{Register}{None}\\[6pt] Inverts the bits of the target register. \section{SHR (Shift Right)} - \OpcodeTable{0x90}{1001 0000}{shr}{Register}{Constant}\\[6pt] + \OpcodeTable{0x88}{1000 1000}{shr}{Register}{Constant}\\[6pt] Bit-wise shifts the contents of the register right Constant number of times. \section{SHL (Shift Left)} - \OpcodeTable{0x98}{1001 1000}{shl}{Register}{Constant}\\[6pt] + \OpcodeTable{0x90}{1001 0000}{shl}{Register}{Constant}\\[6pt] Bit-wise shifts the contents of the register left Constant number of times. \section{INC (Increment)} - \OpcodeTable{0xA0}{1010 0000}{inc}{Register}{None}\\[6pt] + \OpcodeTable{0x98}{1001 1000}{inc}{Register}{None}\\[6pt] Increments the contents of the register by one. Over-flows will not be reported. \section{DEC (Decrement)} - \OpcodeTable{0xA8}{1010 1000}{dec}{Register}{None}\\[6pt] + \OpcodeTable{0xA0}{1010 0000}{dec}{Register}{None}\\[6pt] Decrements the contents of the register by one. Under-flows will not be reported. \section{Push} - \OpcodeTable{0xB0}{1011 0000}{push}{Register}{None} + \OpcodeTable{0xA8}{1010 1000}{push}{Register}{None} Pushes the value of Register onto the stack, decrementing the Stack Pointer by 2. \section{Pop} - \OpcodeTable{0xB8}{1011 1000}{pop}{Register}{None} + \OpcodeTable{0xB0}{1011 0000}{pop}{Register}{None} Pops the top of the stack into Register, incrementing the Stack Pointer by 2. \section{JMPI (Jump Indirect)} - \OpcodeTable{0xC0}{1100 0000}{jmpi}{Register}{None}\\[6pt] + \OpcodeTable{0xB8}{1011 1000}{jmpi}{Register}{None}\\[6pt] Jumps unconditionally to a memory address stored in Operand 1. Sets the Program Counter to Operand 1. \section{JMP (Jump)} \OpcodeTable{0x02}{0000 0010}{jmp}{Address}{None}\\[6pt] diff --git a/includes/opcodes.h b/includes/opcodes.h index 93482b7..6c3955c 100644 --- a/includes/opcodes.h +++ b/includes/opcodes.h @@ -7,47 +7,24 @@ //#include "symbols_table.h" typedef enum { - R1, R2, R3, R4, R5, R6, R7, R8 + R1 = 0, R2, R3, R4, R5, R6, R7, R8 = 7 } Registers; typedef enum { - ADD, SUB, JZ, INT, YLD, RET, - CMP, CMPI, NOP, JMP, CALL, LODW, LAA, LODWI, JE, INC, DEC, LOADB, - STOB, STOW, JG, JL, AND, XOR, OR, NOT, SHR, SHL, POP, PUSH, LODB, - JMPA, JZA, JLA, JGA + COPYA = 0x08, COPYAB = 0x10, COPYRA = 0x18, COPYRAB = 0x20, COPYRARA = 0x28, COPYRARAB = 0x30, COPY = 0x38, COPYB = 0x40, COPYI = 0xC0, + CMP = 0x48, CMPI = 0x50, ADD = 0x58, SUB = 0x60, AND = 0x68, XOR = 0x70, OR = 0x78, NOT = 0x80, SHR = 0x88, SHL = 0x90, + INC = 0x98, DEC = 0xA0, PUSH = 0xA8, POP = 0xB0, + JMPI = 0xB8, JMP = 0x02, JZ = 0x03, JG = 0x04, JL = 0x05, NOP = 0x01, CALL = 0x06, RET = 0x07 } Mnemonic; -typedef enum { - NoParameter = 1, - ConstantParameter = 2, - AddressParameter = 4, - RegisterParameter = 8, - UnresolvedParameter = 16 -} OpcodeParameter; - -typedef struct { - OpcodeParameter ParameterType; - OpcodeParameter InterpretedAs; - - union { - int Number; //ConstanrParam - Registers Register; //Register param - char* Symbol; //Symbol* Symbol; //Address param - } Value; -} Parameter; - typedef struct { Mnemonic Mnemonic; - Parameter* ParameterOne; - Parameter* ParameterTwo; } Instruction; Instruction* CreateInstruction(Mnemonic mnemonic); -Parameter* CreateParameter(OpcodeParameter parameterType); void FreeInstruction(Instruction* instruction); int IsOpcode(const char*, Mnemonic*); int IsRegister(const char*, Registers*); -void ExpectParameters(Mnemonic mnemonic, OpcodeParameter* paramOne, OpcodeParameter* paramTwo); void GetMnemonicText(Mnemonic mnemonic, char buffer[12]); void GetRegisterText(Registers reg, char buffer[3]); unsigned char GetInstructionMask(Mnemonic type); diff --git a/src/opcodes.c b/src/opcodes.c index b36d53c..0466840 100644 --- a/src/opcodes.c +++ b/src/opcodes.c @@ -7,65 +7,43 @@ struct _instruction { char* Name; Mnemonic Mnemonic; - OpcodeParameter ParameterOne; - OpcodeParameter ParameterTwo; }; -struct _instruction instructions[OPCODECOUNT] = { - { "add", ADD, RegisterParameter, RegisterParameter }, - { "sub", SUB, RegisterParameter, RegisterParameter },//, Reg, Reg | Constant }, - { "jz", JZ, AddressParameter, NoParameter },//, Address, None }, - { "yld", YLD, NoParameter, NoParameter },//, None, None }, - { "cmp", CMP, RegisterParameter, RegisterParameter },//, Reg, Reg | Constant }, - { "cmpi", CMPI, RegisterParameter, ConstantParameter }, - { "inc", INC, RegisterParameter, NoParameter },//, Constant | Reg, None}, - { "dec", DEC, RegisterParameter, NoParameter },//, None, None}, - { "nop", NOP, NoParameter, NoParameter },//, None, None}, - { "jmp", JMP, AddressParameter, NoParameter },//, Address, None}, - { "call", CALL, AddressParameter, NoParameter },//, Address, None} - { "lodwi", LODWI, RegisterParameter, ConstantParameter }, - { "je", JE, AddressParameter, NoParameter }, - { "stob", STOB, RegisterParameter, AddressParameter }, - { "stow", STOW, RegisterParameter, AddressParameter }, - { "laa", LAA, RegisterParameter, AddressParameter }, - { "lodw", LODW, RegisterParameter, RegisterParameter }, - { "jmp", JMP, AddressParameter, NoParameter }, - { "jg", JG, AddressParameter, NoParameter }, - { "jl", JL, AddressParameter, NoParameter }, - { "and", AND, RegisterParameter, RegisterParameter }, - { "xor", XOR, RegisterParameter, RegisterParameter }, - { "or", OR, RegisterParameter, RegisterParameter }, - { "not", NOT, RegisterParameter, NoParameter }, - { "shr", SHR, RegisterParameter, ConstantParameter }, - { "shl", SHL, RegisterParameter, ConstantParameter }, - { "nop", NOP, NoParameter, NoParameter }, - { "pop", POP, RegisterParameter, NoParameter }, - { "push", PUSH, RegisterParameter, NoParameter }, - { "lodb", LODB, RegisterParameter, RegisterParameter}, - { "jmpa", JMPA, RegisterParameter, NoParameter}, - { "jza", JZA, RegisterParameter, NoParameter}, - { "jla", JLA, RegisterParameter, NoParameter}, - { "jga", JGA, RegisterParameter, NoParameter}, +struct _instruction instructions[31] = { + { "copya", COPYA }, + { "copyab", COPYAB }, + { "copyra", COPYRA }, + { "copyrab", COPYRAB }, + { "copyrara", COPYRARA }, + { "copyrarab", COPYRARAB }, + { "copy", COPY }, + { "copyi", COPYI }, + { "copyb", COPYB }, + { "cmp", CMP }, + { "cmpi", CMPI }, + { "add", ADD }, + { "sub", SUB }, + { "and", AND }, + { "xor", XOR }, + { "or", OR }, + { "not", NOT }, + { "shr", SHR }, + { "shl", SHL }, + { "inc", INC }, + { "dec", DEC }, + { "push", PUSH }, + { "pop", POP }, + { "jmpi", JMPI }, + { "jmp", JMP }, + { "jz", JZ }, + { "jg", JG }, + { "jl", JL }, + { "nop", NOP }, + { "call", CALL }, + { "ret", RET } + //yld }; -void ExpectParameters(Mnemonic mnemonic, OpcodeParameter* paramOne, OpcodeParameter* paramTwo) { - *paramOne = NoParameter; - *paramTwo = NoParameter; - - for (int i = 0; i < OPCODECOUNT; i++) { - struct _instruction ins = instructions[i]; - - if (ins.Mnemonic == mnemonic) { - *paramOne = ins.ParameterOne; - *paramTwo = ins.ParameterTwo; - - return; - } - } - - fprintf(stderr, "[Warning] Could not find mnemonic (%d) when looking for parameters.\n", mnemonic); -} - Instruction* CreateInstruction(Mnemonic mnemonic) { Instruction* instruction = calloc(1, sizeof(Instruction)); @@ -80,20 +58,6 @@ Instruction* CreateInstruction(Mnemonic mnemonic) { return instruction; } -Parameter* CreateParameter(OpcodeParameter parameterType) { - Parameter* param = calloc(1, sizeof(Parameter)); - - if (!param) { - fprintf(stderr, "Failed to calloc room for a Parameter. %s,\n", strerror(errno)); - - return NULL; - } - - param->ParameterType = parameterType; - - return param; -} - void FreeInstruction(Instruction* instruction) { if (!instruction) return; diff --git a/src/parser.c b/src/parser.c index db45bf8..730b836 100644 --- a/src/parser.c +++ b/src/parser.c @@ -130,42 +130,42 @@ void HandleAssemblerDirective() { if (PeekToken()->Class == NumberClass) { directive->Class = MnemonicClass; - directive->Value.Mnemonic = LODWI; - directive->Lemexe = "LODWI"; + directive->Value.Mnemonic = COPYI; + directive->Lemexe = "copyi"; AdvanceParser(); //Number, register or identifier } else if (PeekToken()->Class == RegisterClass) { directive->Class = MnemonicClass; - directive->Value.Mnemonic = LODW; - directive->Lemexe = "LODW"; + directive->Value.Mnemonic = COPY; + directive->Lemexe = "copy"; AdvanceParser(); //Number, register or identifier } else { ExpectIdentifier(0, ForwardParser); directive->Class = MnemonicClass; - directive->Value.Mnemonic = LAA; - directive->Lemexe = "LAA"; + directive->Value.Mnemonic = COPYA; + directive->Lemexe = "copya"; } } - else if (reg->Class == DirectiveClass) { - if (reg->Value.Directive != Byte) { - fprintf(stderr, "[Line %d] Syntax error, expected keyword 'byte'.\n", reg->LineNumber); - exit(3); - } + // else if (reg->Class == DirectiveClass) { + // if (reg->Value.Directive != Byte) { + // fprintf(stderr, "[Line %d] Syntax error, expected keyword 'byte'.\n", reg->LineNumber); + // exit(3); + // } - RemoveCurrentToken(); //byte + // RemoveCurrentToken(); //byte - ExpectRegister(); + // ExpectRegister(); - ExpectPuncuation(Comma, ForwardParser); + // ExpectPuncuation(Comma, ForwardParser); - ExpectRegister(); + // ExpectRegister(); - directive->Class = MnemonicClass; - directive->Value.Mnemonic = LODB; - directive->Lemexe = "LODB"; - } + // directive->Class = MnemonicClass; + // directive->Value.Mnemonic = LODB; + // directive->Lemexe = "LODB"; + // } ExpectLineEndOrFileEnd(ForwardParser); } @@ -180,9 +180,9 @@ void HandleAssemblerDirective() { if (next->Class != DirectiveClass) { //If the token after the current one is invalid then the expect function ahead will exit, so we can //go ahead and change the STORE directive into a proper opcode here. - directive->Value.Mnemonic = STOW; + directive->Value.Mnemonic = COPY; directive->Class = MnemonicClass; - directive->Lemexe = "STOW"; + directive->Lemexe = "copy"; } else { if (next->Value.Directive != Byte) { @@ -192,9 +192,9 @@ void HandleAssemblerDirective() { RemoveCurrentToken(); //Remove byte modifier token. - directive->Value.Mnemonic = STOB; + directive->Value.Mnemonic = COPYB; directive->Class = MnemonicClass; - directive->Lemexe = "STOB"; + directive->Lemexe = "copyb"; } ExpectRegister(); @@ -272,11 +272,14 @@ void HandleOpcode(void) { { Token* arg = PeekToken(); + opcode->Value.Mnemonic = JMPI; + opcode->Lemexe = "jmpi"; + if (arg->Class == IdentifierClass) { ExpectIdentifier(0, ForwardParser); - opcode->Value.Mnemonic = JMPA; - opcode->Lemexe = "JMPA"; + opcode->Value.Mnemonic = JMP; + opcode->Lemexe = "jmp"; } else ExpectRegister(); } @@ -288,8 +291,8 @@ void HandleOpcode(void) { if (arg->Class == IdentifierClass) { ExpectIdentifier(0, ForwardParser); - opcode->Value.Mnemonic = JZA; - opcode->Lemexe = "JZA"; + opcode->Value.Mnemonic = JZ; + opcode->Lemexe = "jz"; } else ExpectRegister(); } @@ -301,8 +304,8 @@ void HandleOpcode(void) { if (arg->Class == IdentifierClass) { ExpectIdentifier(0, ForwardParser); - opcode->Value.Mnemonic = JGA; - opcode->Lemexe = "JGA"; + opcode->Value.Mnemonic = JG; + opcode->Lemexe = "jg"; } else ExpectRegister(); } @@ -314,8 +317,8 @@ void HandleOpcode(void) { if (arg->Class == IdentifierClass) { ExpectIdentifier(0, ForwardParser); - opcode->Value.Mnemonic = JLA; - opcode->Lemexe = "JLA"; + opcode->Value.Mnemonic = JL; + opcode->Lemexe = "jl"; } else ExpectRegister(); }