Compare commits

...
Author SHA1 Message Date
SonicSwordcane 5d4a422e61 Fix handler address for FIV exception 2025-08-15 00:07:04 -04:00
GuyPerfect 483714c0d6 Pushing current web edits 2025-03-23 07:26:43 -05:00
GuyPerfect ecbd103917 Manage IRQ on writes to INTENB 2025-03-04 10:19:12 -06:00
GuyPerfect b2412d9487 Fix shameful syntax error 2025-03-01 15:51:49 -06:00
GuyPerfect dd1045553b Even more VSU edge cases 2025-03-01 15:42:16 -06:00
GuyPerfect 459a16076a Expand BRTx to 0..132, fix affine parallax 2025-02-25 09:02:22 -06:00
6 changed files with 78 additions and 40 deletions
+1 -1
View File
@@ -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
View File
@@ -361,6 +361,7 @@ struct VB {
/* Other state */
uint32_t clocks; /* Clocks until modification */
uint8_t freqmask; /* Frequency mask */
uint8_t modmask; /* Modifications masked */
uint16_t next; /* Next frequency value */
int sample; /* Current sample index */
+15 -11
View File
@@ -42,14 +42,15 @@ static const uint8_t BG_TEMPLATES[][64] = {
/* 8-bit color magnitude by brightness level */
static const uint8_t BRIGHT8[] = {
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94,
96, 98,100,102,104,106,108,110,112,114,116,118,120,122,124,126,
129,131,133,135,137,139,141,143,145,147,149,151,153,155,157,159,
161,163,165,167,169,171,173,175,177,179,181,183,185,187,189,191,
193,195,197,199,201,203,205,207,209,211,213,215,217,219,221,223,
225,227,229,231,233,235,237,239,241,243,245,247,249,251,253,255
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
};
@@ -435,6 +436,9 @@ static void vipWriteIO(
case 0x5F802>>1: /* INTENB */
sim->vip.intenb = (sim->vip.intenb & mask) | (value & 0xE01F);
if (sim->vip.intenb & sim->vip.intpnd)
sim->cpu.irq |= 0x0010;
else sim->cpu.irq &= ~0x0010;
break;
case 0x5F804>>1: /* INTCLR */
sim->vip.intpnd &= ~value;
@@ -586,7 +590,7 @@ static void vipComputeBrightness(VB *sim) {
/* Transform brightness values to 0..255 */
for (x = 1; x < 4; x++)
sim->vip.dp.brt[x] = brt[x] > 127 ? 255 : BRIGHT8[brt[x]];
sim->vip.dp.brt[x] = brt[x] > 132 ? 255 : BRIGHT8[brt[x]];
}
/* Transfer one column of frame buffer pixels to output */
@@ -1060,8 +1064,8 @@ static void vipDrawAffine(VB *sim, World *world) {
/* Adjust left-edge parameters */
if ((mp < 0) ^ i) {
mx += dx * (wx - mp);
my += dy * (wx - mp);
mx += dx * (wx + mp);
my += dy * (wx + mp);
} else {
mx += dx * wx;
my += dy * wx;
+18 -10
View File
@@ -82,12 +82,12 @@ static void vsuNextFreqMod(VB *sim, Channel *chan) {
/* Modulation */
else {
next = (int32_t) chan->freq.written +
sim->vsu.modulation[sim->vsu.freqmod.sample];
if (next < 0)
next = 0;
if (next > 2047)
next = 2047;
next = ((int32_t) chan->freq.written +
sim->vsu.modulation[sim->vsu.freqmod.sample]) & 0x7FF;
if (sim->vsu.freqmod.freqmask == 1)
next = (next & 0x700) | (chan->freq.written & 0x0FF);
else if (sim->vsu.freqmod.freqmask == 2)
next = (next & 0x0FF) | (chan->freq.written & 0x700);
}
/* Configure state */
@@ -257,7 +257,9 @@ static void vsuWriteFQH(VB *sim, int index, uint16_t value) {
value = value << 8 & 0x0700;
chan->freq.current = (chan->freq.current & 0x00FF) | value;
chan->freq.written = (chan->freq.written & 0x00FF) | value;
if (index == 4)
if (index != 4)
return;
sim->vsu.freqmod.freqmask = 2;
vsuNextFreqMod(sim, chan);
}
@@ -266,7 +268,9 @@ static void vsuWriteFQL(VB *sim, int index, uint8_t value) {
Channel *chan = &sim->vsu.channels[index];
chan->freq.current = (chan->freq.current & 0x0700) | value;
chan->freq.written = (chan->freq.written & 0x0700) | value;
if (index == 4)
if (index != 4)
return;
sim->vsu.freqmod.freqmask = 1;
vsuNextFreqMod(sim, chan);
}
@@ -507,6 +511,7 @@ static void vsuReset(VB *sim) {
sim->vsu.freqmod.clocks = 0;
sim->vsu.freqmod.dir = 0;
sim->vsu.freqmod.enb = 0;
sim->vsu.freqmod.freqmask = 0;
sim->vsu.freqmod.func = 0;
sim->vsu.freqmod.interval = 0;
sim->vsu.freqmod.modmask = 0;
@@ -536,11 +541,14 @@ static void vsuWrite(VB*sim,uint32_t address,int type,int32_t value,int debug){
}
/* Unmapped */
if (address & 3)
if (address & 1)
return;
/* Working variables */
address &= 0x7FF;
address &= 0x7FC;
/* Clear frequency mask */
sim->vsu.freqmod.freqmask = 0;
/* Wave memory */
if (address < 0x280) {
+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.");