From 0fe7dddfdc4bb543181c942db058ed97b5373f5d Mon Sep 17 00:00:00 2001 From: jusax23 Date: Thu, 16 Jun 2022 14:02:01 +0200 Subject: [PATCH] lists --- compiler/output/lists.as | 218 ++++++++++++++++++++++++++++++++++++ compiler/output/lists.b16 | 1 + compiler/scripts/lists.lisp | 11 ++ compiler/tools/lispToAs.js | 186 ++++++++++++++++++++++++------ pico/pico.ino | 139 ++++++++++++++--------- 5 files changed, 464 insertions(+), 91 deletions(-) create mode 100644 compiler/output/lists.as create mode 100644 compiler/output/lists.b16 create mode 100644 compiler/scripts/lists.lisp diff --git a/compiler/output/lists.as b/compiler/output/lists.as new file mode 100644 index 0000000..9dc33cd --- /dev/null +++ b/compiler/output/lists.as @@ -0,0 +1,218 @@ + +v0 = 0;2 +l1 = 2;6 +SHS 8 +;code + + ;defvar: executing value: + + ;num: Loading num + LIA 3 + +; load 0 List element + LIX 0 + SOA 2 l1 + + ;num: Loading num + LIA 2 + +; load 1 List element + LIX 2 + SOA 2 l1 + + ;num: Loading num + LIA 1 + +; load 2 List element + LIX 4 + SOA 2 l1 + +; return List Pointer + LIA l1 + + LIB 65535 + BWA + + ;defvar: Store Value + STA 2 v0 + + ;print: executing value: + +; Load list pointers + + ;num: Loading num + LIA 0 + +; calculate Byte offset + LIB 2 + MUL 0 0 0 + +; Load pointer Address + LIX v0 + + LOB 2 v0 + + ADD 0 0 0 + + CAX +;fetch list-nth + LOA 2 0 + + ;print Value + OUT 0 + + ;print: executing value: + +; Load list pointers + + ;num: Loading num + LIA 1 + +; calculate Byte offset + LIB 2 + MUL 0 0 0 + +; Load pointer Address + LIX v0 + + LOB 2 v0 + + ADD 0 0 0 + + CAX +;fetch list-nth + LOA 2 0 + + ;print Value + OUT 0 + + ;print: executing value: + +; Load list pointers + + ;num: Loading num + LIA 2 + +; calculate Byte offset + LIB 2 + MUL 0 0 0 + +; Load pointer Address + LIX v0 + + LOB 2 v0 + + ADD 0 0 0 + + CAX +;fetch list-nth + LOA 2 0 + + ;print Value + OUT 0 + +;Load value + + ;num: Loading num + LIA 5 + + PSH 2 +; Load list pointers + + ;num: Loading num + LIA 1 + +; calculate Byte offset + LIB 2 + MUL 0 0 0 + +; Load pointer Address + LIX v0 + + LOB 2 v0 + + ADD 0 0 0 + CAX + PUL 2 + +;fetch list-nth + SOA 2 0 + + ;print: executing value: + +; Load list pointers + + ;num: Loading num + LIA 0 + +; calculate Byte offset + LIB 2 + MUL 0 0 0 + +; Load pointer Address + LIX v0 + + LOB 2 v0 + + ADD 0 0 0 + + CAX +;fetch list-nth + LOA 2 0 + + ;print Value + OUT 0 + + ;print: executing value: + +; Load list pointers + + ;num: Loading num + LIA 1 + +; calculate Byte offset + LIB 2 + MUL 0 0 0 + +; Load pointer Address + LIX v0 + + LOB 2 v0 + + ADD 0 0 0 + + CAX +;fetch list-nth + LOA 2 0 + + ;print Value + OUT 0 + + ;print: executing value: + +; Load list pointers + + ;num: Loading num + LIA 2 + +; calculate Byte offset + LIB 2 + MUL 0 0 0 + +; Load pointer Address + LIX v0 + + LOB 2 v0 + + ADD 0 0 0 + + CAX +;fetch list-nth + LOA 2 0 + + ;print Value + OUT 0 + +HLT +;functions + diff --git a/compiler/output/lists.b16 b/compiler/output/lists.b16 new file mode 100644 index 0000000..5d2363e --- /dev/null +++ b/compiler/output/lists.b16 @@ -0,0 +1 @@ +fe00080f0000000312000000000c0200020f0000000212000000020c0200020f0000000112000000040c0200020f00000002100000ffff2f080200000f00000000100000000224000000120000000006020000220000001905020000fd000f00000001100000000224000000120000000006020000220000001905020000fd000f00000002100000000224000000120000000006020000220000001905020000fd000f0000000539020f0000000110000000022400000012000000000602000022000000193a020c0200000f00000000100000000224000000120000000006020000220000001905020000fd000f00000001100000000224000000120000000006020000220000001905020000fd000f00000002100000000224000000120000000006020000220000001905020000fd00ff \ No newline at end of file diff --git a/compiler/scripts/lists.lisp b/compiler/scripts/lists.lisp new file mode 100644 index 0000000..fd9781d --- /dev/null +++ b/compiler/scripts/lists.lisp @@ -0,0 +1,11 @@ +(defvar x:*uint16 (list 3 2 1)) + +(print (list-nth x 0)) +(print (list-nth x 1)) +(print (list-nth x 2)) + +(list-set x 1 5) + +(print (list-nth x 0)) +(print (list-nth x 1)) +(print (list-nth x 2)) diff --git a/compiler/tools/lispToAs.js b/compiler/tools/lispToAs.js index 9210906..45a772d 100644 --- a/compiler/tools/lispToAs.js +++ b/compiler/tools/lispToAs.js @@ -15,6 +15,8 @@ function error(msg,l=null,c=null){ process.exit(1); } +var lispSeperator = [" ",":","\n"]; + function cutCmd(code,line,chars){ if(!code.startsWith("("))return ["",error("Compiler Error",line,chars)]; @@ -86,7 +88,7 @@ function cutCmd(code,line,chars){ countLines++; countChars = 0; } - if((c == " "||c=="\n")&&!inC){ + if(/*(c == " "||c=="\n")*/lispSeperator.includes(c)&&!inC){ if(buffer.trim()!=""){ finishBuff(); } @@ -193,20 +195,32 @@ function getType(data){ var nid = 0; var dataTypes = { - uint32: {ptype:0, length:4, mask:null }, - uint16: {ptype:0, length:2, mask:0xffff }, - uint8: {ptype:0, length:1, mask:0xff }, - int32: {ptype:1, length:4, mask:null }, - int16: {ptype:1, length:2, mask:0xffff }, - int8: {ptype:1, length:1, mask:0xff }, - float: {ptype:2, length:4, mask:null }, - bool: {ptype:0, length:1, mask:1 }, + uint32: {ptype:0, size:4, mask:null }, + uint16: {ptype:0, size:2, mask:0xffff }, + uint8: {ptype:0, size:1, mask:0xff }, + int32: {ptype:1, size:4, mask:null }, + int16: {ptype:1, size:2, mask:0xffff }, + int8: {ptype:1, size:1, mask:0xff }, + float: {ptype:2, size:4, mask:null }, + bool: {ptype:0, size:1, mask:1 }, + + }; + +dataTypes["*uint32"] = {ptype:0, size:2, mask:0xffff, pointing: dataTypes.uint32 }; +dataTypes["*uint16"] = {ptype:0, size:2, mask:0xffff, pointing: dataTypes.uint16 }; +dataTypes["*uint8"] = {ptype:0, size:2, mask:0xffff, pointing: dataTypes.uint8 }; +dataTypes["*int32"] = {ptype:0, size:2, mask:0xffff, pointing: dataTypes.int32 }; +dataTypes["*int16"] = {ptype:0, size:2, mask:0xffff, pointing: dataTypes.int16 }; +dataTypes["*int8"] = {ptype:0, size:2, mask:0xffff, pointing: dataTypes.int8 }; +dataTypes["*float"] = {ptype:0, size:2, mask:0xffff, pointing: dataTypes.float }; +dataTypes["*bool"] = {ptype:0, size:2, mask:0xffff, pointing: dataTypes.bool }; + var dataTypesReversed = { - 0:"uint/bool", + 0:"uint/bool/pointer", 1:"int", 2:"float" -} +}; /*var numTypes = ["uint32", "uint16","uint8","int32","int16","int8","float","bool"];*/ @@ -223,10 +237,16 @@ function find(d,n){ function createVars(c){ var l = 0; return [Object.entries(c).map(d=>{ - var out = `${d[1].id} = ${l};${dataTypes[d[1].type].length}`; - if(d[1].used==0) return ";"+out; - l+=dataTypes[d[1].type].length; - return out; + if(d[1].type=="custom"){ + var out = `${d[1].id} = ${l};${d[1].length}`; + l+=d[1].length; + return out; + }else{ + var out = `${d[1].id} = ${l};${dataTypes[d[1].type].size}`; + if(d[1].used==0) return ";"+out; + l+=dataTypes[d[1].type].size; + return out; + } }).join("\n"),l]; } @@ -243,33 +263,38 @@ function execute(data,expect,context,local){ if(type == "code"){ if(data[0]=="defvar"){ var ctx = last(context); - var [vname,vtype] = data[1].split(":"); + var vname = data[1]; + var vtype = data[2]; + //var [vname,vtype] = data[1].split(":"); if(ctx[vname])error(`Can not redefine: ${cname}! It is already defined!`,...data.pos); if(!dataTypes[vtype])error(`Unknown Datatype: ${vtype}`,...data.pos); let mvar = {type:vtype,used:0,id:"v"+nid++,local:local}; ctx["v"+vname] = mvar; - let [c,etype] = execute(data[2],mvar.type,context,local); + let [c,etype] = execute(data[3],mvar.type,context,local); code+= ` ;defvar: executing value: ${c} ;defvar: Store Value - STA ${dataTypes[mvar.type].length|(mvar.local?0x10:0)} ${mvar.id} + STA ${dataTypes[mvar.type].size|(mvar.local?0x10:0)} ${mvar.id} `; ptype = dataTypes[mvar.type].ptype; }else if(data[0]=="defun"){ - var [fname,ftype] = (data[1]??"").split(":"); + var fname = data[1]; + var ftype = data[2]; + //var [fname,ftype] = (data[1]??"").split(":"); if(local)error(`Nested functions are currently not supported: ${fname}`,...data.pos); - if(extrafuns[fname])error(`You can not declare functions double: ${fname}`,...data.pos); - if(!dataTypes[ftype])error(`Unknown Datatype: ${ftype}`,...data.pos); + if(extrafuns[fname])error(`You can not declare functions double: ${fname}`,...fname.pos); + if(!dataTypes[ftype])error(`Unknown Datatype: ${ftype}`,...ftype.pos); var ctx = last(context); var funsCtx = {}; var args = []; var lcode = ""; - data[2].forEach(v=>{ - var [vname,vtype] = v.split(":"); - if(funsCtx[vname])error(`You declared the Argument ${vname} in function",fname,"twice!`,...data.pos); - if(!dataTypes[vtype])error(`Unknown Datatype: ${vtype}`,...data.pos); + for (var i = 0; i < data[3].length; i++) { + let vname = data[3][i]; + let vtype = data[3][i+1]; + if(funsCtx[vname])error(`You declared the Argument ${vname} in function",fname,"twice!`,...vname.pos); + if(!dataTypes[vtype])error(`Unknown Datatype: ${vtype}`,...vtype.pos); var mvarg = {type:vtype,used:1,id:"arg"+nid++,local:false}; var mvarl = {type:vtype,used:1,id:"arg"+nid++,local:true}; @@ -278,10 +303,26 @@ function execute(data,expect,context,local){ ctx["arg_"+vname] = mvarg; lcode+=` ;function copy args - LDA ${dataTypes[mvarg.type].length} ${mvarg.id} - STA ${dataTypes[mvarl.type].length|0x10} ${mvarl.id} + LDA ${dataTypes[mvarg.type].size} ${mvarg.id} + STA ${dataTypes[mvarl.type].size|0x10} ${mvarl.id} ` - }); + } + /*data[3].forEach(v=>{ + var [vname,vtype] = v.split(":"); + if(funsCtx[vname])error(`You declared the Argument ${vname} in function",fname,"twice!`,...vname.pos); + if(!dataTypes[vtype])error(`Unknown Datatype: ${vtype}`,...vtype.pos); + var mvarg = {type:vtype,used:1,id:"arg"+nid++,local:false}; + var mvarl = {type:vtype,used:1,id:"arg"+nid++,local:true}; + + funsCtx["v"+vname] = mvarl; + args.push(mvarg); + ctx["arg_"+vname] = mvarg; + lcode+=` +;function copy args + LDA ${dataTypes[mvarg.type].size} ${mvarg.id} + STA ${dataTypes[mvarl.type].size|0x10} ${mvarl.id} + ` + });*/ var mvar = {type:ftype,used:1,id:"return"+nid++,local:false}; var fun = { type:ftype, @@ -292,7 +333,7 @@ function execute(data,expect,context,local){ extrafuns[fname] = fun; //execute lcode lcode+="\n;function code:\n"; - for (var i = 3; i < data.length; i++) { + for (var i = 4; i < data.length; i++) { let [c,t] = execute(data[i],data.length-1==i?ftype:"any",[...context,funsCtx],true); lcode+=c; } @@ -300,7 +341,7 @@ function execute(data,expect,context,local){ ctx["return_"+fname] = mvar; lcode+= ` ;return from subrutine - STA ${dataTypes[mvar.type].length} ${mvar.id} + STA ${dataTypes[mvar.type].size} ${mvar.id} RSR `; let [localvars,localL] = createVars(funsCtx); @@ -330,7 +371,7 @@ ${lcode} ;let: executing value: ${c} ;let: Store Value - STA ${dataTypes[mvar.type].length|(mvar.local?0x10:0)} ${mvar.id} + STA ${dataTypes[mvar.type].size|(mvar.local?0x10:0)} ${mvar.id} `; ptype = dataTypes[mvar.type].ptype; }else if(data[0]=="+"){ @@ -589,6 +630,81 @@ afterloop${idafter}: }else{ error(`Unknown loop Methode: ${data[1]}`,...data[1].pos); } + }else if(data[0]=="list"){ + var ltype = expect;//data[1]; + if (!ltype.startsWith("*"))error("list requires appropriated context to determine the Datatype requires appropriated context to determine the datatype",...data[0].pos); + if(!dataTypes[ltype])error(`Unknown Datatype: ${ltype}`,...ltype.pos); + let mvar = {type:"custom",length:dataTypes[ltype].pointing.size*(data.length-1),id:"l"+nid++,local:local}; + var ctx = last(context); + ctx["l"+nid++] = mvar; + for (var i = 0; i < data.length-1; i++) { + let [c,t] = execute(data[i+1],ltype.substr(1),context,local); + code+=c; + code+=` +; load ${i} List element + LIX ${i*dataTypes[ltype].size} + SOA ${dataTypes[ltype].size|(mvar.local?0x10:0)} ${mvar.id} + `; + } + + code+=` +; return List Pointer + LIA ${mvar.id} + `; + ptype=0; + }else if(data[0]=="list-nth"){ + var mvar = find(context,"v"+data[1]); + mvar.used++; + if (!mvar.type.startsWith("*"))error("list-nth requires Listpointer as Input.",...data[1].pos); + let [c,etype] = execute(data[2],"uint16",context,local); + code+=` +; Load list pointers +${c} +; calculate Byte offset + LIB ${dataTypes[mvar.type].pointing.size} + MUL 0 0 0 + +; Load pointer Address + LIX ${mvar.id} + + LOB ${2|(mvar.local?0x10:0)} ${mvar.id} + + ADD 0 0 0 + + CAX +;fetch list-nth + LOA ${dataTypes[mvar.type].pointing.size|(mvar.local?0x10:0)} 0 + `; + ptype = dataTypes[mvar.type].pointing.ptype; + }else if(data[0]=="list-set"){ + var mvar = find(context,"v"+data[1]); + mvar.used++; + if (!mvar.type.startsWith("*"))error("list-set requires Listpointer as Input.",...data[1].pos); + let [c1,etype1] = execute(data[2],"uint16",context,local); + let [c2,etype2] = execute(data[3],mvar.type.substr(1),context,local); + code+=` +;Load value +${c2} + PSH ${dataTypes[mvar.type].pointing.size} +; Load list pointers +${c1} +; calculate Byte offset + LIB ${dataTypes[mvar.type].pointing.size} + MUL 0 0 0 + +; Load pointer Address + LIX ${mvar.id} + + LOB ${2|(mvar.local?0x10:0)} ${mvar.id} + + ADD 0 0 0 + CAX + PUL ${dataTypes[mvar.type].pointing.size} + +;fetch list-nth + SOA ${dataTypes[mvar.type].pointing.size|(mvar.local?0x10:0)} 0 + `; + ptype = dataTypes[mvar.type].pointing.ptype; }else{ if(extrafuns[data[0]]){ var fun = extrafuns[data[0]]; @@ -598,14 +714,14 @@ afterloop${idafter}: code+=` ;${i+1} Argument ${ecode} - STA ${dataTypes[fun.args[i].type].length} ${fun.args[i].id} + STA ${dataTypes[fun.args[i].type].size} ${fun.args[i].id} `; } code+=` ;excute function JSR .${data[0]} ;loading return value - LDA ${dataTypes[fun.return.type].length} ${fun.return.id} + LDA ${dataTypes[fun.return.type].size} ${fun.return.id} `; ptype = dataTypes[fun.return.type].ptype; }else{ @@ -618,7 +734,7 @@ afterloop${idafter}: mvar.used++; code += ` ;var: load Variable - LDA ${dataTypes[mvar.type].length|(mvar.local?0x10:0)} ${mvar.id} + LDA ${dataTypes[mvar.type].size|(mvar.local?0x10:0)} ${mvar.id} `; ptype = dataTypes[mvar.type].ptype; }else if(type == "num"||type=="bool"){ @@ -626,7 +742,7 @@ afterloop${idafter}: if(dataTypes[expect]?.ptype == ptype){ code += ` ;num: Loading num - LIA ${dataTypes[expect].mask==null?d:dataTypes[expect].ptype&d} + LIA ${dataTypes[expect].mask==null?d:dataTypes[expect].mask&d} `; doconv = false; }else{ diff --git a/pico/pico.ino b/pico/pico.ino index 6516bbb..ef1f16d 100644 --- a/pico/pico.ino +++ b/pico/pico.ino @@ -58,6 +58,17 @@ void loop() { pram[i] = 0; } } + else if (c=="dump"){ + for(int j = 0; j < 4; j++){ + for(int i = 0; i < 16; i++){ + Serial.print(b16[pram[i]>>4]); + Serial.print(b16[pram[i]&0xf]); + Serial.print(","); + } + Serial.println(); + } + + } else{ for (int i = 0; i < c.length()-1; i=i+2) { prog[i/2] = b16.indexOf(c[i])*16+b16.indexOf(c[i+1]); @@ -104,80 +115,87 @@ void execute(){ byte n = min(s&0xf,4); unsigned short data = prog[pcounter++]<<8; data += prog[pcounter++]; - unsigned short addr = ((s&0xf0)!=0)?max(pframepointer+1-data-n,pstackpointer):data; - /*Serial.print("LDA"); - Serial.print(s); - Serial.print(">"); - Serial.print(s&0xf0); - Serial.print(">"); - Serial.print((s&0xf0)!=0); - Serial.print(">"); - Serial.print(max(pframepointer+1-data-n,pstackpointer)); - Serial.print(">"); - Serial.print(pframepointer-data-n); - Serial.print(">"); - Serial.println(addr);*/ + boolean local = ((s&0xf0)!=0); + data = local?pframepointer-data:data; AReg = 0; for (byte i = 0; i < n; i++) { - AReg += pram[addr+i]<<(i*8); + AReg += pram[data+i*(local?-1:1)]<<(i*8); } }break; case 2:{ // LDB - byte n = min(prog[pcounter++],4); + byte s = prog[pcounter++]; + byte n = min(s&0xf,4); unsigned short data = prog[pcounter++]<<8; data += prog[pcounter++]; + boolean local = ((s&0xf0)!=0); + data = local?pframepointer-data:data; BReg = 0; for (byte i = 0; i < n; i++) { - BReg += pram[data+i]<<(i*8); + BReg += pram[data+i*(local?-1:1)]<<(i*8); } }break; case 3:{ // LDC - byte n = min(prog[pcounter++],4); + byte s = prog[pcounter++]; + byte n = min(s&0xf,4); unsigned short data = prog[pcounter++]<<8; data += prog[pcounter++]; + boolean local = ((s&0xf0)!=0); + data = local?pframepointer-data:data; CReg = 0; for (byte i = 0; i < n; i++) { - CReg += pram[data+i]<<(i*8); + CReg += pram[data+i*(local?-1:1)]<<(i*8); } }break; case 4:{ // LDX - byte n = min(prog[pcounter++],4); + byte s = prog[pcounter++]; + byte n = min(s&0xf,4); unsigned short data = prog[pcounter++]<<8; data += prog[pcounter++]; + boolean local = ((s&0xf0)!=0); + data = local?pframepointer-data:data; XReg = 0; for (byte i = 0; i < n; i++) { - XReg += pram[data+i]<<(i*8); + XReg += pram[data+i*(local?-1:1)]<<(i*8); } }break; case 5:{ // LOA - byte n = min(prog[pcounter++],4); + byte s = prog[pcounter++]; + byte n = min(s&0xf,4); unsigned short data = prog[pcounter++]<<8; data += prog[pcounter++]; - data += XReg*n; + boolean local = ((s&0xf0)!=0); + data += XReg;//*n; + data = local?pframepointer-data:data; AReg = 0; for (byte i = 0; i < n; i++) { - AReg += pram[data+i]<<(i*8); + AReg += pram[data+i*(local?-1:1)]<<(i*8); } }break; case 6:{ // LOB - byte n = min(prog[pcounter++],4); + byte s = prog[pcounter++]; + byte n = min(s&0xf,4); unsigned short data = prog[pcounter++]<<8; data += prog[pcounter++]; - data += XReg*n; + boolean local = ((s&0xf0)!=0); + data += XReg;//*n; + data = local?pframepointer-data:data; BReg = 0; for (byte i = 0; i < n; i++) { - BReg += pram[data+i]<<(i*8); + BReg += pram[data+i*(local?-1:1)]<<(i*8); } }break; case 7:{ // LOC - byte n = min(prog[pcounter++],4); + byte s = prog[pcounter++]; + byte n = min(s&0xf,4); unsigned short data = prog[pcounter++]<<8; data += prog[pcounter++]; - data += XReg*n; + boolean local = ((s&0xf0)!=0); + data += XReg;//*n; + data = local?pframepointer-data:data; CReg = 0; for (byte i = 0; i < n; i++) { - CReg += pram[data+i]<<(i*8); + CReg += pram[data+i*(local?-1:1)]<<(i*8); } }break; @@ -186,71 +204,80 @@ void execute(){ byte n = min(s&0xf,4); unsigned short data = prog[pcounter++]<<8; data += prog[pcounter++]; - unsigned short addr = ((s&0xf0)!=0)?max(pframepointer+1-data-n,pstackpointer):data; - /*Serial.print("STA"); - Serial.print(s); - Serial.print(">"); - Serial.print(s&0xf0); - Serial.print(">"); - Serial.print((s&0xf0)!=0); - Serial.print(">"); - Serial.print(max(pframepointer+1-data-n,pstackpointer)); - Serial.print(">"); - Serial.println(addr);*/ + boolean local = ((s&0xf0)!=0); + data = local?pframepointer-data:data; for (byte i = 0; i < n; i++) { - pram[addr+i] = (AReg>>(i*8))&0xff; + pram[data+i*(local?-1:1)] = (AReg>>(i*8))&0xff; } }break; case 9:{ // STB - byte n = min(prog[pcounter++],4); + byte s = prog[pcounter++]; + byte n = min(s&0xf,4); unsigned short data = prog[pcounter++]<<8; data += prog[pcounter++]; + boolean local = ((s&0xf0)!=0); + data = local?pframepointer-data:data; for (byte i = 0; i < n; i++) { - pram[data+i] = (BReg>>(i*8))&0xff; + pram[data+i*(local?-1:1)] = (BReg>>(i*8))&0xff; } }break; case 10:{ // STC - byte n = min(prog[pcounter++],4); + byte s = prog[pcounter++]; + byte n = min(s&0xf,4); unsigned short data = prog[pcounter++]<<8; data += prog[pcounter++]; + boolean local = ((s&0xf0)!=0); + data = local?pframepointer-data:data; for (byte i = 0; i < n; i++) { - pram[data+i] = (CReg>>(i*8))&0xff; + pram[data+i*(local?-1:1)] = (CReg>>(i*8))&0xff; } }break; case 11:{ // STX - byte n = min(prog[pcounter++],4); + byte s = prog[pcounter++]; + byte n = min(s&0xf,4); unsigned short data = prog[pcounter++]<<8; data += prog[pcounter++]; + boolean local = ((s&0xf0)!=0); + data = local?pframepointer-data:data; for (byte i = 0; i < n; i++) { - pram[data+i] = (XReg>>(i*8))&0xff; + pram[data+i*(local?-1:1)] = (XReg>>(i*8))&0xff; } }break; case 12:{ // SOA - byte n = min(prog[pcounter++],4); + byte s = prog[pcounter++]; + byte n = min(s&0xf,4); unsigned short data = prog[pcounter++]<<8; data += prog[pcounter++]; - data += XReg*n; + boolean local = ((s&0xf0)!=0); + data += XReg;//*n; + data = local?pframepointer-data:data; for (byte i = 0; i < n; i++) { - pram[data+i] = (AReg>>(i*8))&0xff; + pram[data+i*(local?-1:1)] = (AReg>>(i*8))&0xff; } }break; case 13:{ // SOB - byte n = min(prog[pcounter++],4); + byte s = prog[pcounter++]; + byte n = min(s&0xf,4); unsigned short data = prog[pcounter++]<<8; data += prog[pcounter++]; - data += XReg*n; + boolean local = ((s&0xf0)!=0); + data += XReg;//*n; + data = local?pframepointer-data:data; for (byte i = 0; i < n; i++) { - pram[data+i] = (BReg>>(i*8))&0xff; + pram[data+i*(local?-1:1)] = (BReg>>(i*8))&0xff; } }break; case 14:{ // SOC - byte n = min(prog[pcounter++],4); + byte s = prog[pcounter++]; + byte n = min(s&0xf,4); unsigned short data = prog[pcounter++]<<8; data += prog[pcounter++]; - data += XReg*n; + boolean local = ((s&0xf0)!=0); + data += XReg;//*n; + data = local?pframepointer-data:data; for (byte i = 0; i < n; i++) { - pram[data+i] = (CReg>>(i*8))&0xff; + pram[data+i*(local?-1:1)] = (CReg>>(i*8))&0xff; } }break;