Skip to content

Commit

Permalink
feat: fix trace and update libraries to get inx instr working again
Browse files Browse the repository at this point in the history
  • Loading branch information
goblinoats committed Sep 18, 2023
1 parent af7e6d5 commit 516b73c
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 85 deletions.
8 changes: 5 additions & 3 deletions circuits/helpers/src/addressing.nr
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,17 @@ fn acc(
}

fn imp(
op_sorted_addr: [Field; 1],
op_sorted_val: [Field; 1],
op_sorted_op_rw: [Field; 1],
op_sorted_addr: [Field; 2],
op_sorted_val: [Field; 2],
op_sorted_op_rw: [Field; 2],
) {
//kind of a do nothing mode
// PC is read,
assert(op_sorted_addr[0] == 8203);
assert(op_sorted_op_rw[0] == 0);

// value at PC is read and thrown away
assert(op_sorted_op_rw[1] == 0);
}

fn imm(
Expand Down
81 changes: 67 additions & 14 deletions circuits/helpers/src/lib.nr
Original file line number Diff line number Diff line change
@@ -1,19 +1,57 @@
mod addressing;
mod permutation;

fn compute_zn_status(number: Field) -> u8 {
let mut bits = 0 as u8;
struct Status {
C: u16, // Carry
Z: u16, // Zero
I: u16, // Disable Interrupt
D: u16, // Decimal Mode
B: u16, // Break
U: u16, // Unused
V: u16, // Overflow
N: u16, // Negative
}

unconstrained fn convert_to_status(n: Field) -> Status {
let number = n as u16;
let status = Status {
C: number & 1,
Z: number & 2,
I: number & 4,
D: number & 8,
B: number & 16,
U: number & 32,
V: number & 64,
N: number & 128
};
status
}

unconstrained fn status_to_num(status: Status) -> Field {
let mut number = 0 as u16;
number = number | status.C & 1;
number = number | status.Z & 2;
number = number | status.I & 4;
number = number | status.D & 8;
number = number | status.B & 16;
number = number | status.U & 32;
number = number | status.V & 64;
number = number | status.N & 128;
number as Field
}

fn compute_zn_status(number: Field, mut status: Status) -> Status {
// let mut bits = 0 as u8;
if (number == 0) {
bits = bits & 2;
status.Z = 1;
// bits = bits & 2;
}
if (number as u8 > 127) {
bits = bits & 128;
status.N = 1;
// bits = bits & 128;
}
bits
}

fn update_status(status: Field, new: u8)-> Field {
((status as u8) & new) as Field
// bits
status
}

fn wrapping_add_u16(a: Field, b: Field) -> Field {
Expand Down Expand Up @@ -53,9 +91,9 @@ fn acc(
)
}
fn imp(
op_sorted_addr: [Field; 1],
op_sorted_val: [Field; 1],
op_sorted_op_rw: [Field; 1],
op_sorted_addr: [Field; 2],
op_sorted_val: [Field; 2],
op_sorted_op_rw: [Field; 2],
) {
addressing::imp(
op_sorted_addr,
Expand Down Expand Up @@ -167,14 +205,29 @@ fn idy(
)
}

fn compute_permutation(
fn compute_permutation_9(
r: Field,
op_sorted_step: [Field; 9],
op_sorted_addr: [Field; 9],
op_sorted_val: [Field; 9],
op_sorted_op_rw: [Field; 9]
) -> Field {
permutation::compute_9(
r,
op_sorted_step,
op_sorted_addr,
op_sorted_val,
op_sorted_op_rw
)
}
fn compute_permutation_21(
r: Field,
op_sorted_step: [Field; 21],
op_sorted_addr: [Field; 21],
op_sorted_val: [Field; 21],
op_sorted_op_rw: [Field; 21]
) -> Field {
permutation::compute(
permutation::compute_21(
r,
op_sorted_step,
op_sorted_addr,
Expand Down
13 changes: 12 additions & 1 deletion circuits/helpers/src/permutation.nr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

fn compute(
fn compute_21(
r: Field,
op_sorted_step: [Field; 21],
op_sorted_addr: [Field; 21],
Expand All @@ -8,4 +8,15 @@ fn compute(
) -> Field {
// TODO: implement
0
}

fn compute_9(
r: Field,
op_sorted_step: [Field; 9],
op_sorted_addr: [Field; 9],
op_sorted_val: [Field; 9],
op_sorted_op_rw: [Field; 9]
) -> Field {
// TODO: implement
0
}
141 changes: 75 additions & 66 deletions circuits/instr/inx/src/main.nr
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use dep::helpers;
use dep::std;


//PC = 8203
Expand All @@ -8,71 +9,79 @@ use dep::helpers;
//SR = 8205
fn main(
r: Field,
op_sorted_step: [Field; 10],
op_sorted_addr: [Field; 10],
op_sorted_val: [Field; 10],
op_sorted_op_rw: [Field; 10]
op_sorted_step: [Field; 9],
op_sorted_addr: [Field; 9],
op_sorted_val: [Field; 9],
op_sorted_op_rw: [Field; 9]
) -> pub Field {


assert(op_sorted_addr[0] == 8203);
assert(op_sorted_op_rw[0] == 0);
let pc = op_sorted_val[0];

// the value here should map to the addr of the next entry
// but we need to implement "mapping" logic, and I don't
// have good ideas on how to do that at present
assert(op_sorted_op_rw[0] == 0);
assert(op_sorted_op_rw[1] == 0);
assert(op_sorted_val[1] == 232);
// this is especially annoying because mappers are stateful
// so it's going to be unconstrained for now
//assert(op_sorted_addr[1] == ??);

// this the address read value should be the opcode
assert(op_sorted_val[1] == 232);
assert(op_sorted_op_rw[1] == 0);

//next update the PC
assert(op_sorted_addr[2] == 8203);
assert(op_sorted_op_rw[2] == 1);
assert(op_sorted_val[2] == pc + 1);

let mut sub_arr_addr: [Field; 2] = [0,0];
let mut sub_arr_val: [Field; 2] = [0,0];
let mut sub_arr_op_rw: [Field; 2] = [0,0];
for i in 2..3 {
sub_arr_addr[i] = op_sorted_addr[i];
sub_arr_val[i] = op_sorted_val[i];
sub_arr_op_rw[i] = op_sorted_op_rw[i];
let offset = 3;
for i in 0..2 {
sub_arr_addr[i] = op_sorted_addr[offset + i];
sub_arr_val[i] = op_sorted_val[offset + i];
sub_arr_op_rw[i] = op_sorted_op_rw[offset + i];
}

let address: Field = helpers::imm(
helpers::imp(
sub_arr_addr,
sub_arr_val,
sub_arr_op_rw
);

// add the offset to the index
index = index + address;

// we perform a read of x
assert(op_sorted_addr[index] == 8201);
assert(op_sorted_op_rw[index] == 0);
let value = op_sorted_val[index];
index = index + 1;
assert(op_sorted_addr[5] == 8201);
assert(op_sorted_op_rw[5] == 0);
let value = op_sorted_val[5];

// we then perform a write of x + 1
assert(op_sorted_addr[index] == 8201);
assert(op_sorted_op_rw[index] == 1);
assert(op_sorted_addr[6] == 8201);
assert(op_sorted_op_rw[6] == 1);
let wadd = helpers::wrapping_add_u8(value, 1);
assert(op_sorted_val[index] == wadd.value);
index = index + 1;
assert(op_sorted_val[6] == wadd.value);

// we then set a new status into the status register

// first there is a read from the status register
assert(op_sorted_addr[index] == 8205);
assert(op_sorted_op_rw[index] == 0);
let sr = op_sorted_val[index];
index = index + 1;
assert(op_sorted_addr[7] == 8205);
assert(op_sorted_op_rw[7] == 0);
let sr = op_sorted_val[7];

// std::println(wadd);
let mut status = helpers::convert_to_status(sr);

// next there is a write to the status register
// we need to compute the zero and negative flag
let zn = helpers::compute_zn_status(wadd.value);
let srnew = helpers::update_status(sr, zn);
assert(op_sorted_addr[index] == 8205);
assert(op_sorted_op_rw[index] == 1);
assert(op_sorted_val[index] == srnew);
index = index + 1;
status = helpers::compute_zn_status(wadd.value, status);
let comp_status = helpers::status_to_num(status);
// std::println(status);
assert(op_sorted_addr[8] == 8205);
assert(op_sorted_op_rw[8] == 1);
assert(op_sorted_val[8] == comp_status);

// Compute permutation and return it
helpers::compute_permutation(
helpers::compute_permutation_9(
r,
op_sorted_step,
op_sorted_addr,
Expand All @@ -82,62 +91,62 @@ fn main(
}

#[test]
fn test_0() {
fn test_0() -> Field {
main(
1,
[405465, 405466, 405467, 405468, 405469, 405470, 405471, 405472, 405473, 405474, 405475],
[8203, 79, 8205, 8203, 8203, 80, 8205, 8201, 8201, 8205, 8205],
[49231, 232, 36, 49232, 49232, 224, 36, 0, 1, 36, 36],
[0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1]
[343432, 343433, 343434, 343435, 343436, 343437, 343438, 343439, 343440],
[8203, 79, 8203, 8203, 80, 8201, 8201, 8205, 8205],
[49231, 232, 49232, 49232, 224, 0, 1, 36, 36],
[0, 0, 1, 0, 0, 0, 1, 0, 1]
)
}
#[test]
fn test_1() {
fn test_1() -> Field {
main(
1,
[405540, 405541, 405542, 405543, 405544, 405545, 405546, 405547, 405548, 405549, 405550],
[8203, 79, 8205, 8203, 8203, 80, 8205, 8201, 8201, 8205, 8205],
[49231, 232, 36, 49232, 49232, 224, 36, 1, 2, 36, 36],
[0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1]
[343492, 343493, 343494, 343495, 343496, 343497, 343498, 343499, 343500],
[8203, 79, 8203, 8203, 80, 8201, 8201, 8205, 8205],
[49231, 232, 49232, 49232, 224, 1, 2, 36, 36],
[0, 0, 1, 0, 0, 0, 1, 0, 1]
)
}
#[test]
fn test_2() {
fn test_2() -> Field {
main(
1,
[405615, 405616, 405617, 405618, 405619, 405620, 405621, 405622, 405623, 405624, 405625],
[8203, 79, 8205, 8203, 8203, 80, 8205, 8201, 8201, 8205, 8205],
[49231, 232, 36, 49232, 49232, 224, 36, 2, 3, 36, 36],
[0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1]
[343552, 343553, 343554, 343555, 343556, 343557, 343558, 343559, 343560],
[8203, 79, 8203, 8203, 80, 8201, 8201, 8205, 8205],
[49231, 232, 49232, 49232, 224, 2, 3, 36, 36],
[0, 0, 1, 0, 0, 0, 1, 0, 1]
)
}
#[test]
fn test_3() {
fn test_3() -> Field {
main(
1,
[405690, 405691, 405692, 405693, 405694, 405695, 405696, 405697, 405698, 405699, 405700],
[8203, 79, 8205, 8203, 8203, 80, 8205, 8201, 8201, 8205, 8205],
[49231, 232, 36, 49232, 49232, 224, 36, 3, 4, 36, 36],
[0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1]
[343612, 343613, 343614, 343615, 343616, 343617, 343618, 343619, 343620],
[8203, 79, 8203, 8203, 80, 8201, 8201, 8205, 8205],
[49231, 232, 49232, 49232, 224, 3, 4, 36, 36],
[0, 0, 1, 0, 0, 0, 1, 0, 1]
)
}
#[test]
fn test_4() {
fn test_4() -> Field {
main(
1,
[405765, 405766, 405767, 405768, 405769, 405770, 405771, 405772, 405773, 405774, 405775],
[8203, 79, 8205, 8203, 8203, 80, 8205, 8201, 8201, 8205, 8205],
[49231, 232, 36, 49232, 49232, 224, 36, 4, 5, 36, 36],
[0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1]
[343672, 343673, 343674, 343675, 343676, 343677, 343678, 343679, 343680],
[8203, 79, 8203, 8203, 80, 8201, 8201, 8205, 8205],
[49231, 232, 49232, 49232, 224, 4, 5, 36, 36],
[0, 0, 1, 0, 0, 0, 1, 0, 1]
)
}
#[test]
fn test_5() {
fn test_5() -> Field {
main(
1,
[405840, 405841, 405842, 405843, 405844, 405845, 405846, 405847, 405848, 405849, 405850],
[8203, 79, 8205, 8203, 8203, 80, 8205, 8201, 8201, 8205, 8205],
[49231, 232, 36, 49232, 49232, 224, 36, 5, 6, 36, 36],
[0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1]
[343732, 343733, 343734, 343735, 343736, 343737, 343738, 343739, 343740],
[8203, 79, 8203, 8203, 80, 8201, 8201, 8205, 8205],
[49231, 232, 49232, 49232, 224, 5, 6, 36, 36],
[0, 0, 1, 0, 0, 0, 1, 0, 1]
)
}
1 change: 1 addition & 0 deletions emulator/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ roms/
tmp/
test_results*
target/
trace.json
2 changes: 1 addition & 1 deletion emulator/src/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ impl Cpu {
// The IRQ status at the end of the second-to-last cycle is what matters,
// so keep the second-to-last status.
self.prev_run_irq = self.run_irq;
self.run_irq = !self.irq.is_empty() && !self.status().intersects(Status::I);
self.run_irq = !self.irq.is_empty() && !self.status.intersects(Status::I);
if self.run_irq {
log::trace!("IRQ Level Detected: {}: {:?}", self.cycle, self.irq);
}
Expand Down
Loading

0 comments on commit 516b73c

Please sign in to comment.