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:
parent
07f3a30c96
commit
11f7347a15
@ -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?
|
||||||
|
@ -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;
|
||||||
|
@ -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");
|
||||||
|
Loading…
Reference in New Issue
Block a user