Skip to content

Instantly share code, notes, and snippets.

@niconii
Last active November 26, 2016 08:48
Show Gist options
  • Save niconii/563fe64cea293ecdbdf7033641397dc2 to your computer and use it in GitHub Desktop.
Save niconii/563fe64cea293ecdbdf7033641397dc2 to your computer and use it in GitHub Desktop.
A little toy CPU with only a mov instruction
fn main() {
let mut ram = [0u16; 0x2000];
let mut rom = [0xffffu16; 0xc000];
{
let mut ptr = 0x0000;
let mut mov = |dst, src| {
rom[ptr+0] = src;
rom[ptr+1] = dst;
ptr += 2;
};
for ch in "Hello, world!".chars() {
mov(0x0280, ch as u16);
}
}
let rom = rom;
let mut cpu = Cpu::new(&mut ram, &rom);
while cpu.step() { }
}
struct Cpu<'a> {
ram: &'a mut [u16; 0x2000],
rom: &'a [u16; 0xc000],
alus: [u16; 32],
pc: u16
}
impl<'a> Cpu<'a> {
fn new(ram: &'a mut [u16; 0x2000], rom: &'a [u16; 0xc000]) -> Cpu<'a> {
Cpu {
ram: ram,
rom: rom,
alus: [0u16; 32],
pc: 0x4000
}
}
fn step(&mut self) -> bool {
let src = self.read(self.pc as usize + 0);
let dst = self.read(self.pc as usize + 1);
self.pc += 2;
let n = self.read(src as usize);
self.write(dst as usize, n)
}
fn read(&self, addr: usize) -> u16 {
match addr {
0x0000...0x00ff => addr as u16,
0x0100...0x01ff => self.alus[addr/8],
0x0200 => self.pc,
0x2000...0x3fff => self.ram[addr-0x2000],
0x4000...0xffff => self.rom[addr-0x4000],
_ => 0xff
}
}
fn write(&mut self, addr: usize, n: u16) -> bool {
match addr {
0x0100...0x01ff => match addr % 8 {
0 => self.alus[addr/8] = n,
1 => self.alus[addr/8] += n,
2 => self.alus[addr/8] -= n,
3 => self.alus[addr/8] &= n,
4 => self.alus[addr/8] |= n,
5 => self.alus[addr/8] ^= n,
6 => self.alus[addr/8] >>= n,
7 => {
let a = self.read(n as usize);
self.alus[addr/8] = a;
},
_ => { }
},
0x0200 => self.pc = n,
0x0280 => print!("{}", n as u8 as char),
0x2000...0x3fff => self.ram[addr-0x2000] = n,
0xffff => return false,
_ => { }
}
true
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment