Cleaned up store and load instructions

This commit is contained in:
JJ Bliss
2026-04-30 16:13:49 -04:00
parent 09779e9134
commit 30f9c86c22
+91 -71
View File
@@ -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")!;