diff options
Diffstat (limited to 'src/types/instruction.rs')
-rw-r--r-- | src/types/instruction.rs | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/src/types/instruction.rs b/src/types/instruction.rs new file mode 100644 index 0000000..646a06f --- /dev/null +++ b/src/types/instruction.rs @@ -0,0 +1,168 @@ +use crate::*; + +use Operation as Op; + + +pub struct Instruction { + pub value: u8, +} + +impl Instruction { + pub fn operation(&self) -> Operation { + match self.value & 0x1f { + 0x00=>Op::HLT, 0x01=>Op::PSH, 0x02=>Op::POP, 0x03=>Op::CPY, + 0x04=>Op::DUP, 0x05=>Op::OVR, 0x06=>Op::SWP, 0x07=>Op::ROT, + 0x08=>Op::JMP, 0x09=>Op::JMS, 0x0a=>Op::JCN, 0x0b=>Op::JCS, + 0x0c=>Op::LDA, 0x0d=>Op::STA, 0x0e=>Op::LDD, 0x0f=>Op::STD, + 0x10=>Op::ADD, 0x11=>Op::SUB, 0x12=>Op::INC, 0x13=>Op::DEC, + 0x14=>Op::LTH, 0x15=>Op::GTH, 0x16=>Op::EQU, 0x17=>Op::NQK, + 0x18=>Op::SHL, 0x19=>Op::SHR, 0x1a=>Op::ROL, 0x1b=>Op::ROR, + 0x1c=>Op::IOR, 0x1d=>Op::XOR, 0x1e=>Op::AND, 0x1f=>Op::NOT, + _ => unreachable!(), + } + } + + pub fn return_mode(&self) -> bool { + self.value & RETURN_MODE != 0 + } + + pub fn immediate_mode(&self) -> bool { + self.value & IMMEDIATE_MODE != 0 + } + + pub fn wide_mode(&self) -> bool { + self.value & WIDE_MODE != 0 + } +} + +impl std::fmt::Display for Instruction { + fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { + write!(f, "{}", match self.value { + // Stack operators + 0x00=>"HLT",0x20=>"NOP" ,0x40=>"DB1" ,0x60=>"DB2" ,0x80=>"DB3" ,0xA0=>"DB4" ,0xC0=>"DB5" ,0xE0=>"DB6" , + 0x01=>"PSH",0x21=>"PSH*",0x41=>"PSH:",0x61=>"PSH*:",0x81=>"PSHr",0xA1=>"PSHr*",0xC1=>"PSHr:",0xE1=>"PSHr*:", + 0x02=>"POP",0x22=>"POP*",0x42=>"POP:",0x62=>"POP*:",0x82=>"POPr",0xA2=>"POPr*",0xC2=>"POPr:",0xE2=>"POPr*:", + 0x03=>"CPY",0x23=>"CPY*",0x43=>"CPY:",0x63=>"CPY*:",0x83=>"CPYr",0xA3=>"CPYr*",0xC3=>"CPYr:",0xE3=>"CPYr*:", + 0x04=>"DUP",0x24=>"DUP*",0x44=>"DUP:",0x64=>"DUP*:",0x84=>"DUPr",0xA4=>"DUPr*",0xC4=>"DUPr:",0xE4=>"DUPr*:", + 0x05=>"OVR",0x25=>"OVR*",0x45=>"OVR:",0x65=>"OVR*:",0x85=>"OVRr",0xA5=>"OVRr*",0xC5=>"OVRr:",0xE5=>"OVRr*:", + 0x06=>"SWP",0x26=>"SWP*",0x46=>"SWP:",0x66=>"SWP*:",0x86=>"SWPr",0xA6=>"SWPr*",0xC6=>"SWPr:",0xE6=>"SWPr*:", + 0x07=>"ROT",0x27=>"ROT*",0x47=>"ROT:",0x67=>"ROT*:",0x87=>"ROTr",0xA7=>"ROTr*",0xC7=>"ROTr:",0xE7=>"ROTr*:", + // Control operators + 0x08=>"JMP",0x28=>"JMP*",0x48=>"JMP:",0x68=>"JMP*:",0x88=>"JMPr",0xA8=>"JMPr*",0xC8=>"JMPr:",0xE8=>"JMPr*:", + 0x09=>"JMS",0x29=>"JMS*",0x49=>"JMS:",0x69=>"JMS*:",0x89=>"JMSr",0xA9=>"JMSr*",0xC9=>"JMSr:",0xE9=>"JMSr*:", + 0x0A=>"JCN",0x2A=>"JCN*",0x4A=>"JCN:",0x6A=>"JCN*:",0x8A=>"JCNr",0xAA=>"JCNr*",0xCA=>"JCNr:",0xEA=>"JCNr*:", + 0x0B=>"JCS",0x2B=>"JCS*",0x4B=>"JCS:",0x6B=>"JCS*:",0x8B=>"JCSr",0xAB=>"JCSr*",0xCB=>"JCSr:",0xEB=>"JCSr*:", + 0x0C=>"LDA",0x2C=>"LDA*",0x4C=>"LDA:",0x6C=>"LDA*:",0x8C=>"LDAr",0xAC=>"LDAr*",0xCC=>"LDAr:",0xEC=>"LDAr*:", + 0x0D=>"STA",0x2D=>"STA*",0x4D=>"STA:",0x6D=>"STA*:",0x8D=>"STAr",0xAD=>"STAr*",0xCD=>"STAr:",0xED=>"STAr*:", + 0x0E=>"LDD",0x2E=>"LDD*",0x4E=>"LDD:",0x6E=>"LDD*:",0x8E=>"LDDr",0xAE=>"LDDr*",0xCE=>"LDDr:",0xEE=>"LDDr*:", + 0x0F=>"STD",0x2F=>"STD*",0x4F=>"STD:",0x6F=>"STD*:",0x8F=>"STDr",0xAF=>"STDr*",0xCF=>"STDr:",0xEF=>"STDr*:", + // Numeric operators + 0x10=>"ADD",0x30=>"ADD*",0x50=>"ADD:",0x70=>"ADD*:",0x90=>"ADDr",0xB0=>"ADDr*",0xD0=>"ADDr:",0xF0=>"ADDr*:", + 0x11=>"SUB",0x31=>"SUB*",0x51=>"SUB:",0x71=>"SUB*:",0x91=>"SUBr",0xB1=>"SUBr*",0xD1=>"SUBr:",0xF1=>"SUBr*:", + 0x12=>"INC",0x32=>"INC*",0x52=>"INC:",0x72=>"INC*:",0x92=>"INCr",0xB2=>"INCr*",0xD2=>"INCr:",0xF2=>"INCr*:", + 0x13=>"DEC",0x33=>"DEC*",0x53=>"DEC:",0x73=>"DEC*:",0x93=>"DECr",0xB3=>"DECr*",0xD3=>"DECr:",0xF3=>"DECr*:", + 0x14=>"LTH",0x34=>"LTH*",0x54=>"LTH:",0x74=>"LTH*:",0x94=>"LTHr",0xB4=>"LTHr*",0xD4=>"LTHr:",0xF4=>"LTHr*:", + 0x15=>"GTH",0x35=>"GTH*",0x55=>"GTH:",0x75=>"GTH*:",0x95=>"GTHr",0xB5=>"GTHr*",0xD5=>"GTHr:",0xF5=>"GTHr*:", + 0x16=>"EQU",0x36=>"EQU*",0x56=>"EQU:",0x76=>"EQU*:",0x96=>"EQUr",0xB6=>"EQUr*",0xD6=>"EQUr:",0xF6=>"EQUr*:", + 0x17=>"NQK",0x37=>"NQK*",0x57=>"NQK:",0x77=>"NQK*:",0x97=>"NQKr",0xB7=>"NQKr*",0xD7=>"NQKr:",0xF7=>"NQKr*:", + // Bitwise operators + 0x18=>"SHL",0x38=>"SHL*",0x58=>"SHL:",0x78=>"SHL*:",0x98=>"SHLr",0xB8=>"SHLr*",0xD8=>"SHLr:",0xF8=>"SHLr*:", + 0x19=>"SHR",0x39=>"SHR*",0x59=>"SHR:",0x79=>"SHR*:",0x99=>"SHRr",0xB9=>"SHRr*",0xD9=>"SHRr:",0xF9=>"SHRr*:", + 0x1A=>"ROL",0x3A=>"ROL*",0x5A=>"ROL:",0x7A=>"ROL*:",0x9A=>"ROLr",0xBA=>"ROLr*",0xDA=>"ROLr:",0xFA=>"ROLr*:", + 0x1B=>"ROR",0x3B=>"ROR*",0x5B=>"ROR:",0x7B=>"ROR*:",0x9B=>"RORr",0xBB=>"RORr*",0xDB=>"RORr:",0xFB=>"RORr*:", + 0x1C=>"IOR",0x3C=>"IOR*",0x5C=>"IOR:",0x7C=>"IOR*:",0x9C=>"IORr",0xBC=>"IORr*",0xDC=>"IORr:",0xFC=>"IORr*:", + 0x1D=>"XOR",0x3D=>"XOR*",0x5D=>"XOR:",0x7D=>"XOR*:",0x9D=>"XORr",0xBD=>"XORr*",0xDD=>"XORr:",0xFD=>"XORr*:", + 0x1E=>"AND",0x3E=>"AND*",0x5E=>"AND:",0x7E=>"AND*:",0x9E=>"ANDr",0xBE=>"ANDr*",0xDE=>"ANDr:",0xFE=>"ANDr*:", + 0x1F=>"NOT",0x3F=>"NOT*",0x5F=>"NOT:",0x7F=>"NOT*:",0x9F=>"NOTr",0xBF=>"NOTr*",0xDF=>"NOTr:",0xFF=>"NOTr*:", + }) + } +} + +impl std::str::FromStr for Instruction { + type Err = (); + + fn from_str(token: &str) -> Result<Self, Self::Err> { + Ok( Instruction { value: match token { + // Stack operators + "HLT"=>0x00,"NOP" =>0x20,"DB1" =>0x40,"DB2" =>0x60,"DB3" =>0x80,"DB4" =>0xA0,"DB5" =>0xC0,"DB6" =>0xE0, + "PSH"=>0x01,"PSH*"=>0x21,"PSH:"=>0x41,"PSH*:"=>0x61,"PSHr"=>0x81,"PSHr*"=>0xA1,"PSHr:"=>0xC1,"PSHr*:"=>0xE1, + ":"=>0x41, "*:"=>0x61, "r:"=>0xC1, "r*:"=>0xE1, + "POP"=>0x02,"POP*"=>0x22,"POP:"=>0x42,"POP*:"=>0x62,"POPr"=>0x82,"POPr*"=>0xA2,"POPr:"=>0xC2,"POPr*:"=>0xE2, + "CPY"=>0x03,"CPY*"=>0x23,"CPY:"=>0x43,"CPY*:"=>0x63,"CPYr"=>0x83,"CPYr*"=>0xA3,"CPYr:"=>0xC3,"CPYr*:"=>0xE3, + "DUP"=>0x04,"DUP*"=>0x24,"DUP:"=>0x44,"DUP*:"=>0x64,"DUPr"=>0x84,"DUPr*"=>0xA4,"DUPr:"=>0xC4,"DUPr*:"=>0xE4, + "OVR"=>0x05,"OVR*"=>0x25,"OVR:"=>0x45,"OVR*:"=>0x65,"OVRr"=>0x85,"OVRr*"=>0xA5,"OVRr:"=>0xC5,"OVRr*:"=>0xE5, + "SWP"=>0x06,"SWP*"=>0x26,"SWP:"=>0x46,"SWP*:"=>0x66,"SWPr"=>0x86,"SWPr*"=>0xA6,"SWPr:"=>0xC6,"SWPr*:"=>0xE6, + "ROT"=>0x07,"ROT*"=>0x27,"ROT:"=>0x47,"ROT*:"=>0x67,"ROTr"=>0x87,"ROTr*"=>0xA7,"ROTr:"=>0xC7,"ROTr*:"=>0xE7, + // Control operators + "JMP"=>0x08,"JMP*"=>0x28,"JMP:"=>0x48,"JMP*:"=>0x68,"JMPr"=>0x88,"JMPr*"=>0xA8,"JMPr:"=>0xC8,"JMPr*:"=>0xE8, + "JMS"=>0x09,"JMS*"=>0x29,"JMS:"=>0x49,"JMS*:"=>0x69,"JMSr"=>0x89,"JMSr*"=>0xA9,"JMSr:"=>0xC9,"JMSr*:"=>0xE9, + "JCN"=>0x0A,"JCN*"=>0x2A,"JCN:"=>0x4A,"JCN*:"=>0x6A,"JCNr"=>0x8A,"JCNr*"=>0xAA,"JCNr:"=>0xCA,"JCNr*:"=>0xEA, + "JCS"=>0x0B,"JCS*"=>0x2B,"JCS:"=>0x4B,"JCS*:"=>0x6B,"JCSr"=>0x8B,"JCSr*"=>0xAB,"JCSr:"=>0xCB,"JCSr*:"=>0xEB, + "LDA"=>0x0C,"LDA*"=>0x2C,"LDA:"=>0x4C,"LDA*:"=>0x6C,"LDAr"=>0x8C,"LDAr*"=>0xAC,"LDAr:"=>0xCC,"LDAr*:"=>0xEC, + "STA"=>0x0D,"STA*"=>0x2D,"STA:"=>0x4D,"STA*:"=>0x6D,"STAr"=>0x8D,"STAr*"=>0xAD,"STAr:"=>0xCD,"STAr*:"=>0xED, + "LDD"=>0x0E,"LDD*"=>0x2E,"LDD:"=>0x4E,"LDD*:"=>0x6E,"LDDr"=>0x8E,"LDDr*"=>0xAE,"LDDr:"=>0xCE,"LDDr*:"=>0xEE, + "STD"=>0x0F,"STD*"=>0x2F,"STD:"=>0x4F,"STD*:"=>0x6F,"STDr"=>0x8F,"STDr*"=>0xAF,"STDr:"=>0xCF,"STDr*:"=>0xEF, + // Numeric operators + "ADD"=>0x10,"ADD*"=>0x30,"ADD:"=>0x50,"ADD*:"=>0x70,"ADDr"=>0x90,"ADDr*"=>0xB0,"ADDr:"=>0xD0,"ADDr*:"=>0xF0, + "SUB"=>0x11,"SUB*"=>0x31,"SUB:"=>0x51,"SUB*:"=>0x71,"SUBr"=>0x91,"SUBr*"=>0xB1,"SUBr:"=>0xD1,"SUBr*:"=>0xF1, + "INC"=>0x12,"INC*"=>0x32,"INC:"=>0x52,"INC*:"=>0x72,"INCr"=>0x92,"INCr*"=>0xB2,"INCr:"=>0xD2,"INCr*:"=>0xF2, + "DEC"=>0x13,"DEC*"=>0x33,"DEC:"=>0x53,"DEC*:"=>0x73,"DECr"=>0x93,"DECr*"=>0xB3,"DECr:"=>0xD3,"DECr*:"=>0xF3, + "LTH"=>0x14,"LTH*"=>0x34,"LTH:"=>0x54,"LTH*:"=>0x74,"LTHr"=>0x94,"LTHr*"=>0xB4,"LTHr:"=>0xD4,"LTHr*:"=>0xF4, + "GTH"=>0x15,"GTH*"=>0x35,"GTH:"=>0x55,"GTH*:"=>0x75,"GTHr"=>0x95,"GTHr*"=>0xB5,"GTHr:"=>0xD5,"GTHr*:"=>0xF5, + "EQU"=>0x16,"EQU*"=>0x36,"EQU:"=>0x56,"EQU*:"=>0x76,"EQUr"=>0x96,"EQUr*"=>0xB6,"EQUr:"=>0xD6,"EQUr*:"=>0xF6, + "NQK"=>0x17,"NQK*"=>0x37,"NQK:"=>0x57,"NQK*:"=>0x77,"NQKr"=>0x97,"NQKr*"=>0xB7,"NQKr:"=>0xD7,"NQKr*:"=>0xF7, + // Bitwise operators + "SHL"=>0x18,"SHL*"=>0x38,"SHL:"=>0x58,"SHL*:"=>0x78,"SHLr"=>0x98,"SHLr*"=>0xB8,"SHLr:"=>0xD8,"SHLr*:"=>0xF8, + "SHR"=>0x19,"SHR*"=>0x39,"SHR:"=>0x59,"SHR*:"=>0x79,"SHRr"=>0x99,"SHRr*"=>0xB9,"SHRr:"=>0xD9,"SHRr*:"=>0xF9, + "ROL"=>0x1A,"ROL*"=>0x3A,"ROL:"=>0x5A,"ROL*:"=>0x7A,"ROLr"=>0x9A,"ROLr*"=>0xBA,"ROLr:"=>0xDA,"ROLr*:"=>0xFA, + "ROR"=>0x1B,"ROR*"=>0x3B,"ROR:"=>0x5B,"ROR*:"=>0x7B,"RORr"=>0x9B,"RORr*"=>0xBB,"RORr:"=>0xDB,"RORr*:"=>0xFB, + "IOR"=>0x1C,"IOR*"=>0x3C,"IOR:"=>0x5C,"IOR*:"=>0x7C,"IORr"=>0x9C,"IORr*"=>0xBC,"IORr:"=>0xDC,"IORr*:"=>0xFC, + "XOR"=>0x1D,"XOR*"=>0x3D,"XOR:"=>0x5D,"XOR*:"=>0x7D,"XORr"=>0x9D,"XORr*"=>0xBD,"XORr:"=>0xDD,"XORr*:"=>0xFD, + "AND"=>0x1E,"AND*"=>0x3E,"AND:"=>0x5E,"AND*:"=>0x7E,"ANDr"=>0x9E,"ANDr*"=>0xBE,"ANDr:"=>0xDE,"ANDr*:"=>0xFE, + "NOT"=>0x1F,"NOT*"=>0x3F,"NOT:"=>0x5F,"NOT*:"=>0x7F,"NOTr"=>0x9F,"NOTr*"=>0xBF,"NOTr:"=>0xDF,"NOTr*:"=>0xFF, + _ => return Err(()), + }}) + } +} + + +pub enum Operation { + HLT, PSH, POP, CPY, + DUP, OVR, SWP, ROT, + JMP, JMS, JCN, JCS, + LDA, STA, LDD, STD, + ADD, SUB, INC, DEC, + LTH, GTH, EQU, NQK, + SHL, SHR, ROL, ROR, + IOR, XOR, AND, NOT, +} + +impl From<Operation> for u8 { + fn from(operation: Operation) -> Self { + match operation { + Op::HLT=>0x00, Op::PSH=>0x01, Op::POP=>0x02, Op::CPY=>0x03, + Op::DUP=>0x04, Op::OVR=>0x05, Op::SWP=>0x06, Op::ROT=>0x07, + Op::JMP=>0x08, Op::JMS=>0x09, Op::JCN=>0x0A, Op::JCS=>0x0B, + Op::LDA=>0x0C, Op::STA=>0x0D, Op::LDD=>0x0E, Op::STD=>0x0F, + Op::ADD=>0x10, Op::SUB=>0x11, Op::INC=>0x12, Op::DEC=>0x13, + Op::LTH=>0x14, Op::GTH=>0x15, Op::EQU=>0x16, Op::NQK=>0x17, + Op::SHL=>0x1C, Op::SHR=>0x1D, Op::ROL=>0x1E, Op::ROR=>0x1F, + Op::IOR=>0x18, Op::XOR=>0x19, Op::AND=>0x1A, Op::NOT=>0x1B, + } + } +} + +impl std::fmt::Display for Operation { + fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { + write!(f, "{}", match self { + Op::HLT=>"HLT", Op::PSH=>"PSH", Op::POP=>"POP", Op::CPY=>"CPY", + Op::DUP=>"DUP", Op::OVR=>"OVR", Op::SWP=>"SWP", Op::ROT=>"ROT", + Op::JMP=>"JMP", Op::JMS=>"JMS", Op::JCN=>"JCN", Op::JCS=>"JCS", + Op::LDA=>"LDA", Op::STA=>"STA", Op::LDD=>"LDD", Op::STD=>"STD", + Op::ADD=>"ADD", Op::SUB=>"SUB", Op::INC=>"INC", Op::DEC=>"DEC", + Op::LTH=>"LTH", Op::GTH=>"GTH", Op::EQU=>"EQU", Op::NQK=>"NQK", + Op::SHL=>"SHL", Op::SHR=>"SHR", Op::ROL=>"ROL", Op::ROR=>"ROR", + Op::IOR=>"IOR", Op::XOR=>"XOR", Op::AND=>"AND", Op::NOT=>"NOT", + }) + } +} |