|
|
@@ -97,8 +97,13 @@ function TimerBTick(cia){ |
|
|
|
class MOSCIA{ |
|
|
|
constructor(){ |
|
|
|
this.__regsel = 0; |
|
|
|
this.__RW = 0; |
|
|
|
|
|
|
|
this.__CNT = 0; |
|
|
|
|
|
|
|
this.__SP = 0; |
|
|
|
this.__SPi = 0; |
|
|
|
this.__SData = 0; |
|
|
|
|
|
|
|
this.__PDA = 0; |
|
|
|
this.__PDB = 0; |
|
|
@@ -112,9 +117,9 @@ class MOSCIA{ |
|
|
|
this.__ICMask = 0; |
|
|
|
|
|
|
|
this.__timerA = 0; |
|
|
|
this.__timerALatch = 0; |
|
|
|
this.__timerALatch = 1; |
|
|
|
this.__timerB = 0; |
|
|
|
this.__timerBLatch = 0; |
|
|
|
this.__timerBLatch = 1; |
|
|
|
|
|
|
|
// Time Of Day |
|
|
|
this.__TODLatch = 0; |
|
|
@@ -127,6 +132,9 @@ class MOSCIA{ |
|
|
|
get RS(){return this.__regsel;} |
|
|
|
set RS(rs){this.__regsel = rs & 0x0F;} |
|
|
|
|
|
|
|
get RW(){return this.__RW;} |
|
|
|
set RW(rw){this.__RW = (rw === true || rw === 1) ? 1 : 0;} |
|
|
|
|
|
|
|
get DATA(){ |
|
|
|
let val = 0; |
|
|
|
switch(this.__regsel){ |
|
|
@@ -157,7 +165,7 @@ class MOSCIA{ |
|
|
|
TODLatch(this); |
|
|
|
val = this.__LTOD[3]; break; |
|
|
|
case 0x0C: // Serial Data |
|
|
|
break; |
|
|
|
val = this.__SData; break; |
|
|
|
case 0x0D: // Interrupt Control |
|
|
|
let v = this.__IC; |
|
|
|
this.__IC = 0; |
|
|
@@ -171,6 +179,7 @@ class MOSCIA{ |
|
|
|
} |
|
|
|
|
|
|
|
set DATA(d){ |
|
|
|
if (this.__RW === 1){return;} |
|
|
|
switch(this.__regsel){ |
|
|
|
case 0x00: // Peripheral Data A |
|
|
|
break; |
|
|
@@ -251,16 +260,35 @@ class MOSCIA{ |
|
|
|
if (BITM.isOn(this.__CTA, 0) && BITM.isOn(this.__CTA, 5)) |
|
|
|
TimerATick(this); |
|
|
|
|
|
|
|
if (BITM.isOn(this.__CTB, 0){ |
|
|
|
if (BITM.isOn(this.__CTB, 0)){ |
|
|
|
let cs = (this.__CTB & 0x60) >> 5; |
|
|
|
if (cs === 1) |
|
|
|
TimerBTick(this); |
|
|
|
} |
|
|
|
|
|
|
|
if (BITM.isOn(this.__CTA, 6)){ |
|
|
|
if (this.__SPi > 0){ |
|
|
|
this.__SP = BITM.val(this.__SData, 7); |
|
|
|
this.__SData = this.__SData << 1; |
|
|
|
this.__SPi -= 1; |
|
|
|
if (this.__SPi === 0) |
|
|
|
BITM.set(this.__IC, 3); |
|
|
|
} |
|
|
|
} else { |
|
|
|
if (this.__SPi < 7){ |
|
|
|
this.__SData = (this.__SData << 1) | this.__SP; |
|
|
|
this.__SPi += 1; |
|
|
|
if (this.__SPi === 7) |
|
|
|
BITM.set(this.__IC, 3); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
get SP(){return 0;} |
|
|
|
set SP(b){} |
|
|
|
get SP(){return this.__SP;} |
|
|
|
set SP(sp){ |
|
|
|
this.__SP = (sp === true || sp === 1) ? 1 : 0; |
|
|
|
} |
|
|
|
|
|
|
|
get TOD(){return 0;} |
|
|
|
set TOD(b){ |
|
|
@@ -271,16 +299,51 @@ class MOSCIA{ |
|
|
|
get phi2(){return 0;} |
|
|
|
set phi2(p){ |
|
|
|
if (p >= 1){ |
|
|
|
if (BITM.isOn(this.__CTA, 0) && !BITM.isOn(this.__CTA, 5)){ |
|
|
|
TimerATick(this); |
|
|
|
if (BITM.isOn(this.__CTA, 0)){ |
|
|
|
if (BITM.isOn(cia.__CTA, 1) && !BITM.isOn(cia.__CTA, 2)) |
|
|
|
cia.__PDB = BITM.clear(cia.__PDB, 6); |
|
|
|
|
|
|
|
if (!BITM.isOn(this.__CTA, 5)) |
|
|
|
TimerATick(this); |
|
|
|
} |
|
|
|
if (BITM.isOn(this.__CTB, 0)){ |
|
|
|
if (BITM.isOn(cia.__CTB, 1) && !BITM.isOn(cia.__CTB, 2)) |
|
|
|
cia.__PDB = BITM.clear(cia.__PDB, 7); |
|
|
|
|
|
|
|
let cs = (this.__CTB & 0x60) >> 5; |
|
|
|
if (cs === 0) |
|
|
|
TimerBTick(this); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
reset(){ |
|
|
|
this.__CNT = 0; |
|
|
|
|
|
|
|
this.__PDA = 0; |
|
|
|
this.__PDB = 0; |
|
|
|
this.__DDA = 0; |
|
|
|
this.__DDB = 0; |
|
|
|
|
|
|
|
this.__CTA = 0; |
|
|
|
this.__CTB = 0; |
|
|
|
|
|
|
|
this.__IC = 0; |
|
|
|
this.__ICMask = 0; |
|
|
|
|
|
|
|
this.__timerA = 0; |
|
|
|
this.__timerALatch = 1; |
|
|
|
this.__timerB = 0; |
|
|
|
this.__timerBLatch = 1; |
|
|
|
|
|
|
|
// Time Of Day |
|
|
|
this.__TODLatch = 0; |
|
|
|
this.__TODTick = 0; |
|
|
|
this.__TOD = [0,0,0,0]; |
|
|
|
this.__LTOD = [0,0,0,0]; |
|
|
|
this.__ALTOD = [0,0,0,0]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|