Compare commits

...
14 Commits
7 changed files with 89 additions and 53 deletions
+3 -3
View File
@@ -234,7 +234,7 @@ static int cpuOnExecute(VB *sim) {
#define VB_ON_READ VB_DIRECT_READ
#endif
static int cpuRead(VB *sim, uint32_t address, int type, int32_t *value) {
uint32_t cycles = 4; /* TODO: Research this */
uint32_t cycles = 0; /* TODO: Research this */
/* Retrieve the value from the simulation state directly */
busRead(sim, address, type, value);
@@ -289,7 +289,7 @@ static int cpuReadFetch(VB *sim, int fetch, uint32_t address, int32_t *value) {
#endif
static int cpuWrite(VB *sim, uint32_t address, int type, int32_t value) {
int cancel = 0;
uint32_t cycles = 3; /* TODO: Research this */
uint32_t cycles = 0; /* TODO: Research this */
/* Reset pseudo-halt */
if (sim->ph.enabled)
@@ -495,7 +495,7 @@ static int cpuException(VB *sim) {
sim->cpu.eipc = sim->cpu.pc;
sim->cpu.psw.ep = 1;
sim->cpu.nextPC = 0xFFFF0000 |
((cause & 0xFFF0) == 0xFF60 ? 0xFF60 : cause & 0xFFF0);
((cause & 0xFFF0) == 0xFF70 ? 0xFF60 : cause & 0xFFF0);
}
/* All exceptions */
+1 -1
View File
@@ -900,7 +900,7 @@ VBAPI vbOnWrite vbSetWriteCallback(VB *sim, vbOnWrite callback) {
}
/* Determine the size of a simulation instance */
VBAPI size_t vbSizeOf() {
VBAPI size_t vbSizeOf(void) {
return sizeof (VB);
}
+1 -1
View File
@@ -166,7 +166,7 @@ VBAPI vbOnSamples vbSetSamplesCallback (VB *sim, vbOnSamples callback);
VBAPI uint32_t vbSetSystemRegister (VB *sim, unsigned index, uint32_t value);
VBAPI void* vbSetUserData (VB *sim, void *tag);
VBAPI vbOnWrite vbSetWriteCallback (VB *sim, vbOnWrite callback);
VBAPI size_t vbSizeOf ();
VBAPI size_t vbSizeOf (void);
VBAPI int32_t vbWrite (VB *sim, uint32_t address, int type, int32_t value);
+19 -18
View File
@@ -41,16 +41,17 @@ static const uint8_t BG_TEMPLATES[][64] = {
};
/* 8-bit color magnitude by brightness level */
/* Generated as BRIGHT8[n] = round((n / 132) ** 1.6 * 255) */
static const uint8_t BRIGHT8[] = {
0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 28,
30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 57, 59,
61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 86, 88, 90,
92, 94, 96, 98,100,102,104,106,108,110,112,113,115,117,119,121,
123,125,127,129,131,133,135,137,139,141,142,144,146,148,150,152,
154,156,158,160,162,164,166,168,170,171,173,175,177,179,181,183,
185,187,189,191,193,195,197,198,200,202,204,206,208,210,212,214,
216,218,220,222,224,226,227,229,231,233,235,237,239,241,243,245,
247,249,251,253,255
0, 12, 19, 24, 29, 33, 37, 41, 44, 48, 51, 54, 57, 60, 63, 65,
68, 71, 73, 76, 78, 81, 83, 86, 88, 90, 92, 95, 97, 99,101,103,
105,107,109,111,113,115,117,119,121,123,125,127,128,130,132,134,
136,137,139,141,142,144,146,148,149,151,153,154,156,157,159,161,
162,164,165,167,168,170,172,173,175,176,178,179,181,182,184,185,
186,188,189,191,192,194,195,197,198,199,201,202,203,205,206,208,
209,210,212,213,214,216,217,218,220,221,222,224,225,226,228,229,
230,231,233,234,235,236,238,239,240,242,243,244,245,246,248,249,
250,251,253,254,255
};
@@ -984,7 +985,7 @@ static void vipDrawHBias(VB *sim, World *world) {
/* Process all visible lines */
param = &sim->vip.ram[world->paramBase +
((y1 - world->gy) << 2) + (i << 1)];
for (y = y1; y < y2; y++, param += 2) {
for (y = y1; y < y2; y++, param += 4) {
/* Configure window bounds */
wnd.y1 = y;
@@ -992,7 +993,7 @@ static void vipDrawHBias(VB *sim, World *world) {
/* Draw the background into the window */
vipDrawBackground(sim->vip.shadow[i], &wnd, world,
mx + busReadBuffer(param, VB_S16), my);
mx - busReadBuffer(param, VB_S16), my);
}
}
@@ -1004,7 +1005,7 @@ static void vipDrawAffine(VB *sim, World *world) {
Cell *cell; /* Source cell */
uint8_t *col, *row; /* Output pixel */
uint8_t pixel; /* Character pixel value */
uint8_t *param; /* World parameter memory */
uint32_t param; /* World parameter memory */
int32_t px, py; /* Pixel source coordinates */
int32_t dx, dy, mp, mx, my; /* Affine parameters */
int32_t wx; /* Base world X coordinate */
@@ -1051,16 +1052,16 @@ static void vipDrawAffine(VB *sim, World *world) {
wx = x1 - wx;
/* Process all visible rows */
param = &sim->vip.ram[world->paramBase | (y1 - world->gy) << 4];
param = world->paramBase + ((y1 - world->gy) << 4);
row = &sim->vip.shadow[i][x1 * 224 + y1];
for (y = y1; y < y2; y++, param += 16, row++) {
/* Parse line parameters */
mx = (int32_t) busReadBuffer(param + 0, VB_S16) << 6;
mp = (int32_t) busReadBuffer(param + 2, VB_S16);
my = (int32_t) busReadBuffer(param + 4, VB_S16) << 6;
dx = (int32_t) busReadBuffer(param + 6, VB_S16);
dy = (int32_t) busReadBuffer(param + 8, VB_S16);
mx = (int32_t) busReadBuffer(&sim->vip.ram[param | 0], VB_S16) << 6;
mp = (int32_t) busReadBuffer(&sim->vip.ram[param | 2], VB_S16);
my = (int32_t) busReadBuffer(&sim->vip.ram[param | 4], VB_S16) << 6;
dx = (int32_t) busReadBuffer(&sim->vip.ram[param | 6], VB_S16);
dy = (int32_t) busReadBuffer(&sim->vip.ram[param | 8], VB_S16);
/* Adjust left-edge parameters */
if ((mp < 0) ^ i) {
+27 -17
View File
@@ -132,14 +132,19 @@ static void vsuEmulateChannel(VB *sim, Channel *chan) {
}
/* Envelope modification */
if (chan->env.enb && !chan->env.modmask && chan->env.clocks == 0) {
if (chan->env.clocks == 0) {
uint8_t new_envelope = chan->env.value;
if (chan->env.dir == 0 && chan->env.value != 0)
chan->env.value--;
new_envelope--;
else if (chan->env.dir == 1 && chan->env.value != 15)
chan->env.value++;
else if (chan->env.rep)
chan->env.value = chan->env.reload;
else chan->env.modmask = 1;
new_envelope++;
else if (chan->env.rep && chan->env.modmask != 2) {
new_envelope = chan->env.reload;
chan->env.modmask = 0;
} else if (!chan->env.modmask)
chan->env.modmask = 1;
if (chan->env.enb && !chan->env.modmask)
chan->env.value = new_envelope;
chan->env.clocks = ((uint32_t) chan->env.interval + 1) * 307220;
}
@@ -215,6 +220,7 @@ static void vsuWriteEV0(VB *sim, int index, uint8_t value) {
chan->env.interval = value & 7;
chan->env.value = value >> 4 & 15;
chan->env.reload = chan->env.value;
if (chan->env.modmask == 1) chan->env.modmask = 2;
if (index == 4) {
chan->freqmod = vsuCheckFreqMod(sim);
vsuNextFreqMod(sim, chan);
@@ -231,6 +237,12 @@ static void vsuWriteEV1(VB *sim, int index, uint8_t value) {
/* Parse fields */
chan->env.enb = value & 1;
chan->env.rep = value >> 1 & 1;
if (
!chan->env.rep && (
(chan->env.reload == 0 && chan->env.dir == 0) ||
(chan->env.reload == 15 && chan->env.dir == 1)
)
) chan->env.modmask = 1;
/* Processing by channel */
switch (index) {
@@ -286,7 +298,12 @@ static void vsuWriteINT(VB *sim, int index, uint8_t value) {
/* Update state */
chan->int_.clocks = 76805 * ((uint32_t) chan->int_.interval + 1);
chan->env.modmask = 0;
if (chan->env.enb)
if (
!chan->env.rep && (
(chan->env.reload == 0 && chan->env.dir == 0) ||
(chan->env.reload == 15 && chan->env.dir == 1)
)
) chan->env.modmask = 1;
chan->env.clocks = 307220 * ((uint32_t) chan->env.interval + 1);
if (index != 5) {
chan->wave.sample = 0;
@@ -377,7 +394,7 @@ static void vsuEmulate(VB *sim, uint32_t clocks) {
/* Clocks until next state change */
chan->until = chan->clocks;
if (chan->env.enb && !chan->env.modmask &&
if (chan->env.enb && chan->env.modmask != 2 &&
chan->env.clocks < chan->until)
chan->until = chan->env.clocks;
if (chan->int_.auto_ && chan->int_.clocks < chan->until)
@@ -387,7 +404,7 @@ static void vsuEmulate(VB *sim, uint32_t clocks) {
/* Manage clocks */
chan->clocks -= chan->until;
if (chan->env.enb && !chan->env.modmask)
if (chan->env.enb && chan->env.modmask != 2)
chan->env.clocks -= chan->until;
if (chan->int_.auto_)
chan->int_.clocks -= chan->until;
@@ -531,14 +548,7 @@ static void vsuReset(VB *sim) {
/* Write a typed value to the VSU bus */
static void vsuWrite(VB*sim,uint32_t address,int type,int32_t value,int debug){
/* Only byte writes are allowed */
switch (type) {
case VB_S16:
case VB_U16:
case VB_S32:
return;
}
(void) type;
/* Unmapped */
if (address & 1)
+6
View File
@@ -293,6 +293,12 @@ new class Core {
}, [ output.buffer ]);
}
// Reset simulation state
reset(message) {
this.vbReset(message.sim);
this.dom.postMessage({ promised: true });
}
// Specify anaglyph colors
setAnaglyph(message) {
this.SetAnaglyph(message.sim, message.left, message.right);
+31 -12
View File
@@ -436,8 +436,17 @@ class Sim extends HTMLElement {
response.lines.map(l=>new DasmLine(GUARD, l));
}
// Reset simulation state
reset() {
return this.#core.toCore({
command : "reset",
promised: true,
sim : this.#pointer
});
}
// Specify anaglyph colors
async setAnaglyph(left, right) {
setAnaglyph(left, right) {
// Error checking
if (!Number.isSafeInteger(left ) || left < 0 || left > 0xFFFFFF)
@@ -455,7 +464,7 @@ class Sim extends HTMLElement {
this.#anaglyph[1] = right;
// Send the colors to the core
await this.#core.toCore({
return this.#core.toCore({
command : "setAnaglyph",
promised: true,
sim : this.#pointer,
@@ -475,7 +484,7 @@ class Sim extends HTMLElement {
}
// Specify new game pad keys
async setKeys(keys) {
setKeys(keys) {
// Error checking
if (!Number.isSafeInteger(keys) || keys < 0 || keys > 0xFFFF)
@@ -487,7 +496,7 @@ class Sim extends HTMLElement {
this.#keys = keys;
// Send the keys to the core
await this.#core.toCore({
return this.#core.toCore({
command : "setKeys",
promised: true,
sim : this.#pointer,
@@ -496,7 +505,7 @@ class Sim extends HTMLElement {
}
// Specify audio panning
async setPanning(panning) {
setPanning(panning) {
// Error checking
if (!Number.isFinite(panning) ||panning < -1 || panning > +1) {
@@ -508,7 +517,7 @@ class Sim extends HTMLElement {
this.#panning = panning;
// Send the panning to the core
await this.#core.toCore({
return this.#core.toCore({
command : "setPanning",
promised: true,
sim : this.#pointer,
@@ -529,7 +538,7 @@ class Sim extends HTMLElement {
}
// Specify audio volume
async setVolume(volume) {
setVolume(volume) {
// Error checking
if (!Number.isFinite(volume) ||volume < 0 || volume > 10) {
@@ -541,7 +550,7 @@ class Sim extends HTMLElement {
this.#volume = volume;
// Send the volume to the core
await this.#core.toCore({
return this.#core.toCore({
command : "setVolume",
promised: true,
sim : this.#pointer,
@@ -596,7 +605,7 @@ class VB {
#commands; // Computed method table
#core; // Core worker
#proxy; // Self proxy for sim access
#sims; // All sims
#sims; // Mapping of Sim|pointer -> proxy
#state; // Operations state
@@ -683,8 +692,8 @@ class VB {
///////////////////////////// Static Methods //////////////////////////////
// Create a core instance
static async create(options) {
return await new VB(GUARD).#construct(options);
static create(options) {
return new VB(GUARD).#construct(options);
}
@@ -769,6 +778,16 @@ class VB {
/////////////////////////////// Properties ////////////////////////////////
// Number of managed simulations
get size() { return this.#sims.size / 2; }
// Managed simulations
get sims() { return [... this.#sims.keys()].filter(s=>s instanceof Sim); }
///////////////////////////// Public Methods //////////////////////////////
// Create one or more sims
@@ -809,7 +828,7 @@ class VB {
if (
!Array.isArray(sims) ||
sims.length == 0 ||
sims.find(s=>!this.#sims.has(s))
sims.some(s=>!this.#sims.has(s))
) {
throw new TypeError("Must specify a Sim or array of Sims " +
"that belong to this core.");