--- /dev/null
+`include "ram.v"
+
+`define STATE_INIT 3'd0
+`define STATE_READ_A 3'd1
+`define STATE_READ_B 3'd2
+`define STATE_WRITE 3'd3
+
+`define FLAG_NEWS 4'd8
+`define FLAG_CUBE 4'd9
+`define FLAG_ROUTER 4'd10
+`define FLAG_ROUTER_ACK 4'd11
+`define FLAG_DAISY_CHAIN 4'd12
+`define FLAG_LONG_PARITY 4'd13
+`define FLAG_INPUT 4'd14
+`define FLAG_ZERO 4'd15
+
+`define DIRECTION_N 3'd0
+`define DIRECTION_NE 3'd1
+`define DIRECTION_E 3'd2
+`define DIRECTION_SE 3'd3
+`define DIRECTION_S 3'd4
+`define DIRECTION_SW 3'd5
+`define DIRECTION_W 3'd6
+`define DIRECTION_NW 3'd7
+
+module cpu
+ (input clk, input text[54:0],
+ input cube, input daisy_chain, input pin_input, input router_ack,
+ input [7:0] news_in, output [7:0] news_out,
+ output flag_out, output reg writing_to_router,
+ output mem_in, input mem_out
+);
+
+ wire [3:0] read_flag = text[30:27];
+ wire [3:0] write_flag = text[26:23];
+ wire [3:0] condition_flag = text[22:19];
+ wire condition_sense = text[18];
+ wire [7:0] memory_truth_table = text[17:10];
+ wire [7:0] flag_truth_table = text[9:2];
+ wire [1:0] news_direction = text[1:0];
+
+ reg [7:0] general_flags;
+ reg news_flag;
+ wire [15:0] flags = {1'd0, pin_input, 1'd0, daisy_chain, router_ack, 1'd0, cube, news_flag, general_flags};
+
+ always @* begin
+ flags[7:0] = general_flags[7:0];
+ case(news_direction)
+ `DIRECTION_NORTH: news_flag = north_in;
+ `DIRECTION_EAST: news_flag = east_in;
+ `DIRECTION_WEST: news_flag = west_in;
+ `DIRECTION_SOUTH: news_flag = south_in;
+ endcase // case (news_direction)
+ end
+
+ reg alu_in_a;
+ reg alu_in_b;
+ reg alu_in_f;
+
+ reg alu_index;
+
+ reg alu_out_memory;
+ reg alu_out_flag;
+
+ always @* begin
+ alu_in_f = flags[read_flag];
+ alu_index = (alu_in_a << 2) + (alu_in_b << 1) + alu_in_f;
+
+ alu_out_memory = memory_truth_table[alu_index];
+ alu_out_flag = flag_truth_table[alu_index];
+ end
+
+ assign flag_out = alu_out_flag;
+
+ reg [2:0] state = `STATE_INIT;
+
+ always @ (posedge clk) begin
+ case (state)
+ `STATE_INIT:
+ begin
+ mem_addr <= address_a;
+ state <= `STATE_READ_A
+ end
+
+ `STATE_READ_A:
+ begin
+ alu_in_a <= mem_out;
+ mem_addr <= address_b;
+ mem_write <= 0;
+ writing_to_router <= 0;
+ state <= `STATE_READ_B;
+ end
+
+ `STATE_READ_B:
+ begin
+ alu_in_b <= mem_out;
+ mem_addr <= address_a;
+ state <= `STATE_WRITE;
+ end
+
+ `STATE_WRITE:
+ begin
+ mem_in <= alu_out_memory;
+ mem_write <= 1;
+ state <= `STATE_READ_A;
+
+ if(!write_flag[3])
+ general_flags[write_flag[2:0]] <= alu_out_flag;
+
+ if(write_flag == `FLAG_ROUTER_DATA)
+ writing_to_router <= 1;
+ end
+ endcase
+ end
+
+endmodule
--- /dev/null
+#!/usr/bin/perl
+use v5.14;
+use warnings;
+
+use Device::SerialPort;
+use IPC::Open3;
+use Term::ReadLine;
+use File::Slurp::Tiny qw/read_file/;
+
+my $term;
+
+if (-t) {
+ $term = Term::ReadLine->new('YULE REPL');
+ say "YULE REPL\n";
+}
+
+my $port = Device::SerialPort->new($ARGV[0] // '/dev/ttyUSB1') or die "$!";
+$port->baudrate(300);
+#$port->baudrate(4000000);
+$port->parity('none');
+$port->databits(8);
+$port->stopbits(1);
+$port->handshake('none');
+$port->read_const_time(5000);
+
+$port->write_settings or die "$!";
+
+my $asm = read_file 'cells.clump';
+
+$port->write($asm);
+my ($count_in, $string_in) = $port->read(5000);
+my @memory = unpack 'v*', $string_in;
+for (@memory) {
+ printf "%X ", $_
+}
+
+__END__
+
+while () {
+ my $sexp;
+ if (-t) {
+ $sexp = $term->readline('* ');
+ } else {
+ $sexp = <>;
+ exit unless defined $sexp;
+ chomp $sexp;
+ next unless $sexp;
+ say "* $sexp";
+ }
+ exit unless defined $sexp;
+ next unless $sexp;
+ my $compiler = App::Scheme79asm::Compiler->new;
+ my $compiler_out = $compiler->compile_string($sexp);
+
+# say 'Compiler says: ', dump_sexp($compiler_out);
+
+ my $asm = App::Scheme79asm->new(addr_bits => 13);
+ my $asm_output;
+ open my $asm_fh, '>', \$asm_output;
+ $asm->process($compiler_out);
+ $asm->finish;
+ $asm->print_binary16($asm_fh);
+ close $asm_fh;
+
+# say "Writing: ", join ' ', uc join ' ', unpack '(H2)*', $asm_output;
+ my $bytes_written = $port->write($asm_output);
+ my $bytes_to_write = length $asm_output;
+ die "Only wrote $bytes_written instead of $bytes_to_write" unless $bytes_written == $bytes_to_write;
+
+ my ($count_in, $string_in) = $port->read(5000);
+ my @memory = unpack 'n*', $string_in;
+# say 'Received: ', uc join ' ', unpack '(H2)*', $string_in;
+ unshift @memory, 0, 0, (1<<13), (1<<13);
+ princ $compiler, \@memory, 6;
+ say '';
+}