|
|
@@ -1,6 +1,5 @@ |
|
|
|
const Clock = require('common/clock.js'); |
|
|
|
const BCD = require('utils/bcd.js'); |
|
|
|
const BITM = require('utils/bitman.js'); |
|
|
|
const BCD = require('./utils/bcd.js'); |
|
|
|
const BITM = require('./utils/bitman.js'); |
|
|
|
|
|
|
|
function ChangeICBit(cia, v, pos){ |
|
|
|
let mask = ~(1 << pos); |
|
|
@@ -94,6 +93,54 @@ function TimerBTick(cia){ |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function Tick(cia){ |
|
|
|
if (BITM.isOn(cia.__CTA, 0)){ |
|
|
|
if (BITM.isOn(cia.__CTA, 1) && !BITM.isOn(cia.__CTA, 2)) |
|
|
|
cia.__PDB = BITM.clear(cia.__PDB, 6); |
|
|
|
|
|
|
|
if (!BITM.isOn(cia.__CTA, 5)) |
|
|
|
TimerATick(cia); |
|
|
|
} |
|
|
|
if (BITM.isOn(cia.__CTB, 0)){ |
|
|
|
if (BITM.isOn(cia.__CTB, 1) && !BITM.isOn(cia.__CTB, 2)) |
|
|
|
cia.__PDB = BITM.clear(cia.__PDB, 7); |
|
|
|
|
|
|
|
let cs = (cia.__CTB & 0x60) >> 5; |
|
|
|
if (cs === 0) |
|
|
|
TimerBTick(cia); |
|
|
|
} |
|
|
|
|
|
|
|
if (cia.__CNT === 1){ |
|
|
|
if (BITM.isOn(cia.__CTA, 0) && BITM.isOn(cia.__CTA, 5)) |
|
|
|
TimerATick(cia); |
|
|
|
|
|
|
|
if (BITM.isOn(cia.__CTB, 0)){ |
|
|
|
let cs = (cia.__CTB & 0x60) >> 5; |
|
|
|
if (cs === 1) |
|
|
|
TimerBTick(cia); |
|
|
|
} |
|
|
|
|
|
|
|
if (BITM.isOn(cia.__CTA, 6)){ |
|
|
|
if (cia.__SPi > 0){ |
|
|
|
cia.__SP = BITM.val(cia.__SData, 7); |
|
|
|
cia.__SData = (cia.__SData << 1) & 0xFF; |
|
|
|
cia.__SPi -= 1; |
|
|
|
if (cia.__SPi === 0) |
|
|
|
cia.__IC = BITM.set(cia.__IC, 3); |
|
|
|
} |
|
|
|
} else { |
|
|
|
if (cia.__SPi < 8){ |
|
|
|
cia.__SData = (cia.__SData << 1) | cia.__SP; |
|
|
|
cia.__SPi += 1; |
|
|
|
if (cia.__SPi === 8) |
|
|
|
cia.__IC = BITM.set(cia.__IC, 3); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
cia.__CNT = 0; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
class MOSCIA{ |
|
|
|
constructor(){ |
|
|
|
this.__regsel = 0; |
|
|
@@ -180,6 +227,7 @@ class MOSCIA{ |
|
|
|
|
|
|
|
set DATA(d){ |
|
|
|
if (this.__RW === 1){return;} |
|
|
|
let tod = 0; |
|
|
|
switch(this.__regsel){ |
|
|
|
case 0x00: // Peripheral Data A |
|
|
|
break; |
|
|
@@ -204,25 +252,25 @@ class MOSCIA{ |
|
|
|
case 0x08: // 10th of Sec Reg |
|
|
|
TODLatch(this); |
|
|
|
this.__TODLatch = 2; |
|
|
|
let tod = (BITM.isOn(this.__CTB, 7)) ? this.__ALTOD : this.__TOD; |
|
|
|
tod = (BITM.isOn(this.__CTB, 7)) ? this.__ALTOD : this.__TOD; |
|
|
|
tod[0] = d & 0xFF; |
|
|
|
break; |
|
|
|
case 0x09: // Seconds Reg |
|
|
|
TODLatch(this); |
|
|
|
this.__TODLatch = 2; |
|
|
|
let tod = (BITM.isOn(this.__CTB, 7)) ? this.__ALTOD : this.__TOD; |
|
|
|
tod = (BITM.isOn(this.__CTB, 7)) ? this.__ALTOD : this.__TOD; |
|
|
|
tod[1] = d & 0xFF; |
|
|
|
break; |
|
|
|
case 0x0A: // Minutes Reg |
|
|
|
TODLatch(this); |
|
|
|
this.__TODLatch = 2; |
|
|
|
let tod = (BITM.isOn(this.__CTB, 7)) ? this.__ALTOD : this.__TOD; |
|
|
|
tod = (BITM.isOn(this.__CTB, 7)) ? this.__ALTOD : this.__TOD; |
|
|
|
tod[2] = d & 0xFF; |
|
|
|
break; |
|
|
|
case 0x0B: // Hours AM/PM Reg |
|
|
|
TODLatch(this); |
|
|
|
this.__TODLatch = 2; |
|
|
|
let tod = (BITM.isOn(this.__CTB, 7)) ? this.__ALTOD : this.__TOD; |
|
|
|
tod = (BITM.isOn(this.__CTB, 7)) ? this.__ALTOD : this.__TOD; |
|
|
|
tod[3] = d & 0xFF; |
|
|
|
break; |
|
|
|
case 0x0C: // Serial Data |
|
|
@@ -255,34 +303,7 @@ class MOSCIA{ |
|
|
|
|
|
|
|
get CNT(){return this.__CNT;} |
|
|
|
set CNT(c){ |
|
|
|
this.__CNT = (c >= 1) ? 1 : 0; |
|
|
|
if (this.__CNT === 1){ |
|
|
|
if (BITM.isOn(this.__CTA, 0) && BITM.isOn(this.__CTA, 5)) |
|
|
|
TimerATick(this); |
|
|
|
|
|
|
|
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); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
this.__CNT = (c >= 1) ? 1 : 0; |
|
|
|
} |
|
|
|
|
|
|
|
get SP(){return this.__SP;} |
|
|
@@ -298,22 +319,8 @@ class MOSCIA{ |
|
|
|
|
|
|
|
get phi2(){return 0;} |
|
|
|
set phi2(p){ |
|
|
|
if (p >= 1){ |
|
|
|
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); |
|
|
|
} |
|
|
|
if (p === true || p === 1){ |
|
|
|
Tick(this); |
|
|
|
} |
|
|
|
} |
|
|
|
|