Last active
November 26, 2016 08:48
-
-
Save niconii/563fe64cea293ecdbdf7033641397dc2 to your computer and use it in GitHub Desktop.
A little toy CPU with only a mov instruction
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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