op encoding
This commit is contained in:
commit
f4c78f2b05
|
@ -0,0 +1 @@
|
|||
/target
|
|
@ -0,0 +1,8 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="MarkdownSettingsMigration">
|
||||
<option name="stateVersion" value="1" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/tmcpu.iml" filepath="$PROJECT_DIR$/.idea/tmcpu.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="CPP_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,7 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "tmcpu"
|
||||
version = "0.1.0"
|
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "tmcpu"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
|
@ -0,0 +1,15 @@
|
|||
ldi ra, 0x01
|
||||
ldi rb, 0x02
|
||||
add rc, ra rb ; should be 3
|
||||
out 0x02, rc ; displays 03 on the numeric display
|
||||
|
||||
ldi ra, 0b10100000 ; load the num for red and blue into ra
|
||||
mrm ra, 0x001
|
||||
mrm ra, 0x003
|
||||
mrm ra, 0x01e
|
||||
mrm ra, 0x02e
|
||||
mrm ra, 0x02f
|
||||
mrm ra, 0x030
|
||||
mrm ra, 0x031
|
||||
mrm ra, 0x023
|
||||
; Draw a smiley face
|
|
@ -0,0 +1,5 @@
|
|||
pub mod ops;
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
|
@ -0,0 +1,268 @@
|
|||
pub fn nop() -> Vec<u8> {
|
||||
vec![0b1111_1111]
|
||||
}
|
||||
pub fn hcf() -> Vec<u8> {
|
||||
vec![0b1111_1110]
|
||||
}
|
||||
|
||||
pub enum Register {
|
||||
R0,
|
||||
RA,
|
||||
RB,
|
||||
RC,
|
||||
RD,
|
||||
RE,
|
||||
PC,
|
||||
FLG
|
||||
}
|
||||
impl Register {
|
||||
fn byte(&self) -> u8 {
|
||||
match self {
|
||||
Register::R0 => 0b0000_0000,
|
||||
Register::RA => 0b0000_0001,
|
||||
Register::RB => 0b0000_0010,
|
||||
Register::RC => 0b0000_0011,
|
||||
Register::RD => 0b0000_0100,
|
||||
Register::RE => 0b0000_0101,
|
||||
Register::PC => 0b0000_0110,
|
||||
Register::FLG => 0b0000_0111,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add(reg_dest: Register, reg_a: Register, reg_b: Register) -> Vec<u8> {
|
||||
vec![
|
||||
0b1111_1101, // opcode
|
||||
reg_dest.byte() << 5 | reg_a.byte() << 2, // operands 1
|
||||
reg_b.byte() << 5, // operands 2,
|
||||
0b0000_0000 // operands 3
|
||||
]
|
||||
}
|
||||
|
||||
pub fn sub(reg_dest: Register, reg_a: Register, reg_b: Register) -> Vec<u8> {
|
||||
vec![
|
||||
0b1111_1100, // opcode
|
||||
reg_dest.byte() << 5 | reg_a.byte() << 2, // operands 1
|
||||
reg_b.byte() << 5, // operands 2,
|
||||
0b0000_0000 // operands 3
|
||||
]
|
||||
}
|
||||
|
||||
pub fn or(reg_dest: Register, reg_a: Register, reg_b: Register) -> Vec<u8> {
|
||||
vec![
|
||||
0b1111_1011, // opcode
|
||||
reg_dest.byte() << 5 | reg_a.byte() << 2, // operands 1
|
||||
reg_b.byte() << 5, // operands 2,
|
||||
0b0000_0000 // operands 3
|
||||
]
|
||||
}
|
||||
|
||||
pub fn nor(reg_dest: Register, reg_a: Register, reg_b: Register) -> Vec<u8> {
|
||||
vec![
|
||||
0b1111_1010, // opcode
|
||||
reg_dest.byte() << 5 | reg_a.byte() << 2, // operands 1
|
||||
reg_b.byte() << 5, // operands 2,
|
||||
0b0000_0000 // operands 3
|
||||
]
|
||||
}
|
||||
|
||||
pub fn and(reg_dest: Register, reg_a: Register, reg_b: Register) -> Vec<u8> {
|
||||
vec![
|
||||
0b1111_1001, // opcode
|
||||
reg_dest.byte() << 5 | reg_a.byte() << 2, // operands 1
|
||||
reg_b.byte() << 5, // operands 2,
|
||||
0b0000_0000 // operands 3
|
||||
]
|
||||
}
|
||||
|
||||
pub fn xor(reg_dest: Register, reg_a: Register, reg_b: Register) -> Vec<u8> {
|
||||
vec![
|
||||
0b1111_1000, // opcode
|
||||
reg_dest.byte() << 5 | reg_a.byte() << 2, // operands 1
|
||||
reg_b.byte() << 5, // operands 2,
|
||||
0b0000_0000 // operands 3
|
||||
]
|
||||
}
|
||||
|
||||
pub fn rsh(reg_dest: Register, reg_a: Register) -> Vec<u8> {
|
||||
vec![
|
||||
0b1111_0111, // opcode
|
||||
reg_dest.byte() << 5 | reg_a.byte() << 2, // operands 1
|
||||
0b0000_0000, // operands 2,
|
||||
0b0000_0000 // operands 3
|
||||
]
|
||||
}
|
||||
|
||||
pub fn ldi(reg_dest: Register, immediate: u8) -> Vec<u8> {
|
||||
vec![
|
||||
0b1111_0110, // opcode
|
||||
reg_dest.byte() << 5, // operands 1
|
||||
immediate, // operands 2,
|
||||
0b0000_0000 // operands 3
|
||||
]
|
||||
}
|
||||
|
||||
pub fn mmr(reg_dest: Register, address: u16) -> Vec<u8> {
|
||||
// 0110 1001 1010 0101
|
||||
// want: 1001 1010 0101
|
||||
// &0000 1111 1111 0000, >> 4
|
||||
// &0000 0000 0000 1111, << 4
|
||||
vec![
|
||||
0b1111_0101, // opcode,
|
||||
reg_dest.byte() << 5, // operands 1
|
||||
address_higher_half(address), // operands 2
|
||||
address_lower_half(address), // operands 3
|
||||
]
|
||||
}
|
||||
|
||||
pub fn mrm(reg_src: Register, address: u16) -> Vec<u8> {
|
||||
vec![
|
||||
0b1111_0100, // opcode
|
||||
reg_src.byte() << 5, // operands 1
|
||||
address_higher_half(address), // operands 2
|
||||
address_lower_half(address), // operands 3
|
||||
]
|
||||
}
|
||||
|
||||
pub fn jmp(address: u16) -> Vec<u8> {
|
||||
vec![
|
||||
0b1111_0011, // opcode
|
||||
address_higher_half(address), // operands 1
|
||||
address_lower_half(address), // operands 2,
|
||||
0b0000_0000
|
||||
]
|
||||
}
|
||||
|
||||
pub fn jez(address: u16) -> Vec<u8> {
|
||||
vec![
|
||||
0b1111_0010, // opcode
|
||||
address_higher_half(address), // operands 1
|
||||
address_lower_half(address), // operands 2,
|
||||
0b0000_0000
|
||||
]
|
||||
}
|
||||
|
||||
pub fn rmmr(reg_dest: Register, address: u16) -> Vec<u8> {
|
||||
vec![
|
||||
0b1111_0001, // opcode,
|
||||
reg_dest.byte() << 5, // operands 1
|
||||
address_higher_half(address), // operands 2
|
||||
address_lower_half(address), // operands 3
|
||||
]
|
||||
}
|
||||
|
||||
pub fn r#in(reg_dest: Register, port: u8) -> Vec<u8> {
|
||||
vec![
|
||||
0b1111_0000,
|
||||
reg_dest.byte() << 5,
|
||||
port,
|
||||
0b0000_0000
|
||||
]
|
||||
}
|
||||
|
||||
pub fn out(reg_src: Register, port: u8) -> Vec<u8> {
|
||||
vec![
|
||||
0b1110_1111,
|
||||
reg_src.byte() << 5,
|
||||
port,
|
||||
0b0000_0000
|
||||
]
|
||||
}
|
||||
|
||||
// See `mmr` for how these values are calculated
|
||||
fn address_higher_half(address: u16) -> u8 {
|
||||
((address & 0b0000_1111_1111_0000) >> 4).try_into().unwrap()
|
||||
}
|
||||
// See `mmr` for how these values are calculated
|
||||
fn address_lower_half(address: u16) -> u8 {
|
||||
((address & 0b0000_0000_0000_1111) << 4).try_into().unwrap()
|
||||
}
|
||||
|
||||
mod tests {
|
||||
use crate::ops::{add, and, hcf, jez, jmp, ldi, mmr, mrm, nop, nor, or, out, r#in, Register, rmmr, rsh, sub, xor};
|
||||
|
||||
#[test]
|
||||
fn test_nop() {
|
||||
assert_eq!(nop(), vec![0b1111_1111]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hcf() {
|
||||
assert_eq!(hcf(), vec![0b1111_1110]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add() {
|
||||
assert_eq!(add(Register::R0, Register::RA, Register::RB), vec![0b1111_1101, 0b0000_0100, 0b0100_0000, 0b0000_0000])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sub() {
|
||||
assert_eq!(sub(Register::R0, Register::RA, Register::RB), vec![0b1111_1100, 0b0000_0100, 0b0100_0000, 0b0000_0000])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_or() {
|
||||
assert_eq!(or(Register::R0, Register::RA, Register::RB), vec![0b1111_1011, 0b0000_0100, 0b0100_0000, 0b0000_0000])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nor() {
|
||||
assert_eq!(nor(Register::R0, Register::RA, Register::RB), vec![0b1111_1010, 0b0000_0100, 0b0100_0000, 0b0000_0000])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_and() {
|
||||
assert_eq!(and(Register::R0, Register::RA, Register::RB), vec![0b1111_1001, 0b0000_0100, 0b0100_0000, 0b0000_0000])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_xor() {
|
||||
assert_eq!(xor(Register::R0, Register::RA, Register::RB), vec![0b1111_1000, 0b0000_0100, 0b0100_0000, 0b0000_0000])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rsh() {
|
||||
assert_eq!(rsh(Register::R0, Register::RA), vec![0b1111_0111, 0b0000_0100, 0b0000_0000, 0b0000_0000])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ldi() {
|
||||
assert_eq!(ldi(Register::R0, 0b0101_1010), vec![0b1111_0110, 0b0000_0000, 0b0101_1010, 0b0000_0000])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mmr() {
|
||||
assert_eq!(mmr(Register::R0, 0b0000_0101_1010_0110), vec![0b1111_0101, 0b0000_0000, 0b0101_1010, 0b0110_0000])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mrm() {
|
||||
assert_eq!(mrm(Register::R0, 0b0000_0101_1010_0110), vec![0b1111_0100, 0b0000_0000, 0b0101_1010, 0b0110_0000])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_jmp() {
|
||||
assert_eq!(jmp(0b0000_0101_1010_0110), vec![0b1111_0011, 0b0101_1010, 0b0110_0000, 0b0000_0000])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_jez() {
|
||||
assert_eq!(jez(0b0000_0101_1010_0110), vec![0b1111_0010, 0b0101_1010, 0b0110_0000, 0b0000_0000])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rmmr() {
|
||||
assert_eq!(rmmr(Register::R0, 0b0000_0101_1010_0110), vec![0b1111_0001, 0b0000_0000, 0b0101_1010, 0b0110_0000])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_in() {
|
||||
assert_eq!(r#in(Register::R0, 0b0101_1010), vec![0b1111_0000, 0b0000_0000, 0b0101_1010, 0b0000_0000])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_out() {
|
||||
assert_eq!(out(Register::R0, 0b0101_1010), vec![0b1110_1111, 0b0000_0000, 0b0101_1010, 0b0000_0000])
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue