1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-11-22 14:33:51 +00:00

nanoasm: hack for 32-bit width support

This commit is contained in:
Steven Hugg 2021-06-22 11:20:11 -05:00
parent 07f3a30c96
commit 11f7347a15
3 changed files with 71 additions and 24 deletions

View File

@ -107,6 +107,8 @@ TODO:
- separate Scope View - separate Scope View
- Audio doesn't work if clock != default - Audio doesn't work if clock != default
- change the input values for a module? - change the input values for a module?
- Silice rototexture.ice example bitmap corrupted?
- scope: zoom in on cursor
- single-stepping vector games makes screen fade - single-stepping vector games makes screen fade
- break on stack overflow, illegal op, bad access, BRK, etc - break on stack overflow, illegal op, bad access, BRK, etc
- show in scope instead? - show in scope instead?

View File

@ -223,7 +223,7 @@ export class WaveformView {
var b1 = fh+4; var b1 = fh+4;
var b2 = 4; var b2 = 4;
var h2 = h-b1-b2; var h2 = h-b1-b2;
var yrange = ((1<<meta.len)-1) || 0; var yrange = meta.len == 32 ? 4294967296.0 : ((1<<meta.len)-1) || 0;
var data = this.wfp.getSignalData(row, this.t0, Math.ceil(w/this.zoom)); var data = this.wfp.getSignalData(row, this.t0, Math.ceil(w/this.zoom));
this.clockMax = Math.max(this.clockMax, this.t0 + data.length); this.clockMax = Math.max(this.clockMax, this.t0 + data.length);
var printvals = meta.len > 1 && this.zoom >= 32; var printvals = meta.len > 1 && this.zoom >= 32;

View File

@ -3,12 +3,19 @@ type AssemblerVar = {
bits : number, bits : number,
toks : string[], toks : string[],
iprel? : boolean, iprel? : boolean,
ipofs? : number ipofs? : number,
ipmul? : number,
}
type AssemblerRuleSlice = {
a : number; // argument index
b : number; // bit index
n : number; // # of bits
} }
type AssemblerRule = { type AssemblerRule = {
fmt : string, fmt : string,
bits : (string | number)[], bits : (string | number | AssemblerRuleSlice)[],
// added at runtime // added at runtime
re? : RegExp, re? : RegExp,
prefix? : string, prefix? : string,
@ -22,11 +29,14 @@ type AssemblerLine = {line:number, offset:number, nbits:number, insns?:string};
type AssemblerFixup = { type AssemblerFixup = {
sym:string, sym:string,
ofs:number, ofs:number,
bitlen:number, size:number;
bitofs:number, srcofs:number,
dstofs:number,
dstlen:number,
line:number, line:number,
iprel:boolean, iprel:boolean,
ipofs:number ipofs:number,
ipmul:number,
}; };
type AssemblerSpec = { type AssemblerSpec = {
@ -59,6 +69,9 @@ const isError = (o: AssemblerLineResult): o is AssemblerErrorResult => (<Assembl
function hex(v:number, nd:number) { function hex(v:number, nd:number) {
try { try {
if (!nd) nd = 2; if (!nd) nd = 2;
if (nd == 8) {
return hex((v>>16)&0xffff,4) + hex(v&0xffff,4);
}
var s = v.toString(16).toUpperCase(); var s = v.toString(16).toUpperCase();
while (s.length < nd) while (s.length < nd)
s = "0" + s; s = "0" + s;
@ -161,7 +174,10 @@ export class Assembler {
var op = result.opcode; var op = result.opcode;
var nb = result.nbits/this.width; var nb = result.nbits/this.width;
for (var i=0; i<nb; i++) { for (var i=0; i<nb; i++) {
if (this.width < 32)
this.outwords[this.ip++ - this.origin] = (op >> (nb-1-i)*this.width) & ((1<<this.width)-1); this.outwords[this.ip++ - this.origin] = (op >> (nb-1-i)*this.width) & ((1<<this.width)-1);
else
this.outwords[this.ip++ - this.origin] = op;
} }
} }
addWords(data:number[]) { addWords(data:number[]) {
@ -171,7 +187,10 @@ export class Assembler {
nbits:this.width*data.length nbits:this.width*data.length
}); });
for (var i=0; i<data.length; i++) { for (var i=0; i<data.length; i++) {
if (this.width < 32)
this.outwords[this.ip++ - this.origin] = data[i] & ((1<<this.width)-1); this.outwords[this.ip++ - this.origin] = data[i] & ((1<<this.width)-1);
else
this.outwords[this.ip++ - this.origin] = data[i];
} }
} }
@ -206,17 +225,24 @@ export class Assembler {
var n,x; var n,x;
// is a string? then it's a bit constant // is a string? then it's a bit constant
// TODO // TODO
if (typeof b == "string") { if (typeof b === "string") {
n = b.length; n = b.length;
x = parseInt(b,2); x = parseInt(b,2);
} else { } else {
// is it a slice {a,b,n} or just a number?
var index = typeof b === "number" ? b : b.a;
// it's an indexed variable, look up its variable // it's an indexed variable, look up its variable
var id = m[b+1]; var id = m[index+1];
var v = this.spec.vars[rule.varlist[b]]; var v = this.spec.vars[rule.varlist[index]];
if (!v) { if (!v) {
return {error:"Could not find matching identifier for '" + m[0] + "'"}; return {error:`Could not find matching identifier for '${m[0]}' index ${index}`};
} }
n = v.bits; n = v.bits;
var shift = 0;
if (typeof b !== "number") {
n = b.n;
shift = b.b;
}
// is it an enumerated type? look up the index of its keyword // is it an enumerated type? look up the index of its keyword
if (v.toks) { if (v.toks) {
x = v.toks.indexOf(id); x = v.toks.indexOf(id);
@ -227,14 +253,22 @@ export class Assembler {
x = this.parseConst(id, n); x = this.parseConst(id, n);
// is it a label? add fixup // is it a label? add fixup
if (isNaN(x)) { if (isNaN(x)) {
this.fixups.push({sym:id, ofs:this.ip, bitlen:n, bitofs:oplen, line:this.linenum, iprel:!!v.iprel, ipofs:(v.ipofs+0)}); this.fixups.push({
sym:id, ofs:this.ip, size:v.bits, line:this.linenum,
dstlen:n, dstofs:oplen, srcofs:shift,
iprel:!!v.iprel, ipofs:(v.ipofs+0), ipmul:v.ipmul||1
});
x = 0; x = 0;
} } else {
} var mask = (1<<v.bits)-1;
}
var mask = (1<<n)-1;
if ((x&mask) != x) if ((x&mask) != x)
return {error:"Value " + x + " does not fit in " + n + " bits"}; return {error:"Value " + x + " does not fit in " + v.bits + " bits"};
}
}
if (typeof b !== "number") {
x = (x >>> shift) & ((1 << b.n)-1);
}
}
opcode = (opcode << n) | x; opcode = (opcode << n) | x;
oplen += n; oplen += n;
} }
@ -329,17 +363,28 @@ export class Assembler {
var fix = this.fixups[i]; var fix = this.fixups[i];
var sym = this.symbols[fix.sym]; var sym = this.symbols[fix.sym];
if (sym) { if (sym) {
var ofs = fix.ofs + Math.floor(fix.bitofs/this.width); var ofs = fix.ofs + Math.floor(fix.dstofs/this.width);
var shift = fix.bitofs & (this.width-1); var mask = ((1<<fix.size)-1);
var mask = ((1<<fix.bitlen)-1); var value = this.parseConst(sym.value+"", fix.dstlen);
var value = this.parseConst(sym.value+"", fix.bitlen);
if (fix.iprel) if (fix.iprel)
value -= fix.ofs + fix.ipofs; value = (value - fix.ofs) * fix.ipmul - fix.ipofs;
if (value > mask || value < -mask) if (fix.srcofs == 0 && (value > mask || value < -mask))
this.warning("Symbol " + fix.sym + " (" + value + ") does not fit in " + fix.bitlen + " bits", fix.line); this.warning("Symbol " + fix.sym + " (" + value + ") does not fit in " + fix.dstlen + " bits", fix.line);
value &= mask; //console.log(hex(value,8), fix.srcofs, fix.dstofs, fix.dstlen);
if (fix.srcofs > 0)
value >>>= fix.srcofs;
value &= (1 << fix.dstlen) - 1;
// TODO: make it work for all widths
if (this.width == 32) {
var shift = 32 - fix.dstofs - fix.dstlen;
value <<= shift;
//console.log(fix, shift, fix.dstlen, hex(value,8));
}
// TODO: check range // TODO: check range
// TODO: span multiple words? // TODO: span multiple words?
if (value & this.outwords[ofs - this.origin]) {
//this.warning("Instruction bits overlapped: " + hex(this.outwords[ofs - this.origin],8), hex(value,8));
}
this.outwords[ofs - this.origin] ^= value; // TODO: << shift? this.outwords[ofs - this.origin] ^= value; // TODO: << shift?
} else { } else {
this.warning("Symbol '" + fix.sym + "' not found"); this.warning("Symbol '" + fix.sym + "' not found");