Cleaned up store and load instructions
This commit is contained in:
+91
-71
@@ -425,6 +425,54 @@ fn short_from_bytes(high: u8, low: u8) u16 = {
|
||||
return (high: u16) << 8 | (low: u16);
|
||||
};
|
||||
|
||||
fn read_from_addr(short: bool, addr: u16, state: *uxn) (u8 | u16) = {
|
||||
switch(short){
|
||||
case true =>
|
||||
const high = state.ram[addr];
|
||||
const low = state.ram[addr+1];
|
||||
return short_from_bytes(high,low);
|
||||
|
||||
case false =>
|
||||
return state.ram[addr];
|
||||
};
|
||||
};
|
||||
|
||||
fn write_to_addr(value: (u8 | u16), addr: u16, state: *uxn) void = {
|
||||
match(value){
|
||||
case let s: u16 =>
|
||||
let high = (s >> 8 ): u8;
|
||||
let low = s: u8;
|
||||
state.ram[addr] = high;
|
||||
state.ram[addr+1] = low;
|
||||
|
||||
case let b: u8 =>
|
||||
state.ram[addr] = b;
|
||||
};
|
||||
};
|
||||
|
||||
fn read_from_zaddr(short: bool, zaddr: u8, state: *uxn) (u8 | u16) = {
|
||||
switch(short){
|
||||
case true =>
|
||||
const high = state.ram[zaddr: u16];
|
||||
const low = state.ram[(zaddr+1): u16];
|
||||
return short_from_bytes(high,low);
|
||||
|
||||
case false =>
|
||||
return state.ram[zaddr: u16];
|
||||
};
|
||||
};
|
||||
fn write_to_zaddr(value: (u8 | u16), zaddr: u8, state: *uxn) void = {
|
||||
match(value){
|
||||
case let s: u16 =>
|
||||
let high = (s >> 8 ): u8;
|
||||
let low = s: u8;
|
||||
state.ram[zaddr: u16] = high;
|
||||
state.ram[(zaddr+1): u16] = low;
|
||||
|
||||
case let b: u8 =>
|
||||
state.ram[zaddr: u16] = b;
|
||||
};
|
||||
};
|
||||
|
||||
fn push_to_stack(ret: bool, val: (u8 | u16), state: *uxn) void = {
|
||||
let stack = switch(ret){
|
||||
@@ -448,7 +496,7 @@ fn push_to_stack(ret: bool, val: (u8 | u16), state: *uxn) void = {
|
||||
};
|
||||
};
|
||||
|
||||
// Get value from stack, offset 0 is top of stack.
|
||||
// Get value from stack, offset 0 is top of stack. offset depends on short or byte
|
||||
fn get_stack_val(ret: bool, short: bool, off: u8, state: *uxn) (u8 | u16) = {
|
||||
let stack = switch(ret){
|
||||
case true =>
|
||||
@@ -467,6 +515,26 @@ fn get_stack_val(ret: bool, short: bool, off: u8, state: *uxn) (u8 | u16) = {
|
||||
};
|
||||
};
|
||||
|
||||
//peek offset is always byte offset
|
||||
fn peek(ret: bool, short: bool, off: u8, state: *uxn) (u8 | u16 ) = {
|
||||
let stack = switch(ret){
|
||||
case true =>
|
||||
yield 1;
|
||||
case false =>
|
||||
yield 0;
|
||||
};
|
||||
|
||||
if(!short){
|
||||
let val: u8 = state.stk[stack][state.ptr[stack] - 1 - off];
|
||||
return val;
|
||||
} else {
|
||||
let low: u8 = state.stk[stack][state.ptr[stack] - 1 - off];
|
||||
let high: u8 = state.stk[stack][state.ptr[stack] - 2 - off];
|
||||
return short_from_bytes(high,low);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
fn increment_stack(ret: bool, short: bool, state: *uxn) void = {
|
||||
let stack = switch(ret){
|
||||
case true =>
|
||||
@@ -508,6 +576,15 @@ fn pop_or_get(inst: normal_op, off: u8, state: *uxn) (u8 | u16) = {
|
||||
yield get_stack_val(inst.ret,inst.short, off,state);
|
||||
};
|
||||
};
|
||||
//Offset is always byte aligned in peek
|
||||
fn pop_or_peek(inst: normal_op, off: u8, state: *uxn) (u8 | u16) = {
|
||||
return switch(inst.keep) {
|
||||
case false =>
|
||||
yield pop_from_stack(false,inst.ret,inst.short,state);
|
||||
case true =>
|
||||
yield peek(inst.ret,inst.short, off,state);
|
||||
};
|
||||
};
|
||||
export fn uxn_eval(new_pc: u16, state: *uxn) (done | quit | error ) = {
|
||||
// let a: u16 = 0, b: u16 = 0, c: u16 = 0, x: [2]u16 = [0...], y: [2]u16 = [0...], z: [2]u16 = [0...];
|
||||
state.pc = new_pc;
|
||||
@@ -749,93 +826,36 @@ export fn uxn_step(state: *uxn) (done | error) = {
|
||||
push_to_stack(!sth_inst.ret, val, state);
|
||||
// /* LDZ */ OPC(0x10,POx(a,0),PEK(a, x, 0xff))
|
||||
case let ldz_inst: LDZ =>
|
||||
let addr: u16 = pop_from_stack(ldz_inst.keep, ldz_inst.ret, false, state): u16 & 0x00FF;
|
||||
let val = if(ldz_inst.short){
|
||||
yield short_from_bytes(state.ram[addr],state.ram[addr+1 & 0x00FF]);
|
||||
} else {
|
||||
yield state.ram[addr];
|
||||
};
|
||||
let addr: u8 = pop_from_stack(ldz_inst.keep, ldz_inst.ret, false, state): u8;
|
||||
let val = read_from_zaddr(ldz_inst.short,addr,state);
|
||||
push_to_stack(ldz_inst.ret, val, state);
|
||||
// /* STZ */ OPC(0x11,POx(a,0) GOT(y),POK(a, y, 0xff))
|
||||
case let stz_inst: STZ =>
|
||||
let addr: u16 = pop_or_get(normal_op{short = false, keep = stz_inst.keep, ret = stz_inst.ret}, 0, state): u16 & 0x00FF;
|
||||
let val = if(stz_inst.short){
|
||||
let low = pop_or_get(normal_op{short = false, keep = stz_inst.keep, ret = stz_inst.ret}, 1, state): u8;
|
||||
let high = pop_or_get(normal_op{short = false, keep = stz_inst.keep, ret = stz_inst.ret}, 2, state): u8;
|
||||
yield short_from_bytes(high,low);
|
||||
|
||||
}else{
|
||||
yield pop_or_get(stz_inst, 1, state): u8;
|
||||
};
|
||||
match (val) {
|
||||
case let b: u8 =>
|
||||
state.ram[addr] = b;
|
||||
case let s: u16 =>
|
||||
let high = (s >> 8 ): u8;
|
||||
let low = s: u8;
|
||||
state.ram[addr] = high;
|
||||
state.ram[addr+1 & 0x00FF] = low;
|
||||
//TODO verify correct endianness
|
||||
};
|
||||
let addr: u8 = pop_or_peek(normal_op{short = false, keep = stz_inst.keep, ret = stz_inst.ret}, 0, state): u8;
|
||||
let val = pop_or_peek(stz_inst,1,state);
|
||||
write_to_zaddr(val,addr,state);
|
||||
// /* LDR */ OPC(0x12,POx(a,0),PEK(pc + (Sint8)a, x, 0xffff))
|
||||
case let ldr_inst: LDR =>
|
||||
let reladdr = (pop_from_stack(ldr_inst.keep, ldr_inst.ret, false, state): u16): i8;
|
||||
let addr: u16 = (state.pc: u32: i32 + reladdr): u16;
|
||||
let val = if(ldr_inst.short){
|
||||
yield short_from_bytes(state.ram[addr],state.ram[addr+1]);
|
||||
} else {
|
||||
yield state.ram[addr];
|
||||
};
|
||||
let val = read_from_addr(ldr_inst.short,addr,state);
|
||||
push_to_stack(ldr_inst.ret, val, state);
|
||||
// /* STR */ OPC(0x13,POx(a,0) GOT(y),POK(pc + (Sint8)a, y, 0xffff))
|
||||
case let str_inst: STR =>
|
||||
let reladdr = (pop_or_get(normal_op{short = false, keep = str_inst.keep, ret = str_inst.ret}, 0, state): u16 & 0x00FF): u8: i8;
|
||||
let reladdr = (pop_or_peek(normal_op{short = false, keep = str_inst.keep, ret = str_inst.ret}, 0, state): u16 & 0x00FF): u8: i8;
|
||||
let addr: u16 = (state.pc: u32: i32 + reladdr): u16;
|
||||
let val = if(str_inst.short){
|
||||
let low = pop_or_get(normal_op{short = false, keep = str_inst.keep, ret = str_inst.ret}, 1, state): u8;
|
||||
let high = pop_or_get(normal_op{short = false, keep = str_inst.keep, ret = str_inst.ret}, 2, state): u8;
|
||||
yield short_from_bytes(high,low);
|
||||
|
||||
}else{
|
||||
yield pop_or_get(str_inst, 1, state): u8;
|
||||
};
|
||||
match (val) {
|
||||
case let b: u8 =>
|
||||
state.ram[addr] = b;
|
||||
case let s: u16 =>
|
||||
let high = (s >> 8 ): u8;
|
||||
let low = s: u8;
|
||||
state.ram[addr] = high;
|
||||
state.ram[addr+1] = low;
|
||||
//TODO verify correct endianness
|
||||
};
|
||||
let val = pop_or_peek(str_inst,1,state);
|
||||
write_to_addr(val,addr,state);
|
||||
// /* LDA */ OPC(0x14,POx(a,1),PEK(a, x, 0xffff))
|
||||
case let lda_inst: LDA =>
|
||||
let addr: u16 = pop_from_stack(lda_inst.keep, lda_inst.ret, true, state): u16;
|
||||
let val = if(lda_inst.short){
|
||||
yield short_from_bytes(state.ram[addr],state.ram[addr+1]);
|
||||
} else {
|
||||
yield state.ram[addr];
|
||||
};
|
||||
let val = read_from_addr(lda_inst.short,addr,state);
|
||||
push_to_stack(lda_inst.ret, val, state);
|
||||
// /* STA */ OPC(0x15,POx(a,1) GOT(y),POK(a, y, 0xffff))
|
||||
case let sta_inst: STA =>
|
||||
let addr: u16 = pop_or_get(normal_op{short = true, keep = sta_inst.keep, ret = sta_inst.ret}, 0, state): u16 ;
|
||||
let val = if(sta_inst.short){
|
||||
yield pop_or_get(sta_inst, 1, state): u16;
|
||||
}else{
|
||||
yield pop_or_get(sta_inst, 2, state): u8;
|
||||
};
|
||||
match (val) {
|
||||
case let b: u8 =>
|
||||
state.ram[addr] = b;
|
||||
case let s: u16 =>
|
||||
let high = (s >> 8 ): u8;
|
||||
let low = s: u8;
|
||||
state.ram[addr] = high;
|
||||
state.ram[addr+1] = low;
|
||||
//TODO verify correct endianness
|
||||
};
|
||||
let addr: u16 = pop_or_peek(normal_op{short = true, keep = sta_inst.keep, ret = sta_inst.ret}, 0, state): u16 ;
|
||||
let val = pop_or_peek(sta_inst,2,state);
|
||||
write_to_addr(val,addr,state);
|
||||
// /* DEI */ OPC(0x16,POx(a,0),DEI(a, x))
|
||||
case let dei_inst: DEI =>
|
||||
// fmt::println("DEI Instruction")!;
|
||||
|
||||
Reference in New Issue
Block a user