| const Clock = require('common/clock.js'); | const Clock = require('common/clock.js'); | ||||
| const BCD = require('utils/bcd.js'); | const BCD = require('utils/bcd.js'); | ||||
| const BITM = require('utils/bitman.js'); | |||||
| function ChangeICBit(cia, v, pos){ | function ChangeICBit(cia, v, pos){ | ||||
| let mask = ~(1 << pos); | let mask = ~(1 << pos); | ||||
| cia.__TODTick += 1; | cia.__TODTick += 1; | ||||
| if (cia.__TODTick === 6){ | if (cia.__TODTick === 6){ | ||||
| cia.__TODTick = cia.__CTA & 0x01; | cia.__TODTick = cia.__CTA & 0x01; | ||||
| if (cia.__10ths == 0x09){ | |||||
| cia.__10ths = 0; | |||||
| if (cia.__sec == 0x59){ | |||||
| cia.__sec = 0; | |||||
| if (cia.__min == 0x59){ | |||||
| cia.__min = 0; | |||||
| if (cia.__hour == 0x11 || cia.__hour == 0x91){ | |||||
| cia.__hour = (cia.__hour == 0x91) ? 0x00 : 0x10; | |||||
| if (cia.__TOD[0] == 0x09){ | |||||
| cia.__TOD[0] = 0; | |||||
| if (cia.__TOD[1] == 0x59){ | |||||
| cia.__TOD[1] = 0; | |||||
| if (cia.__TOD[2] == 0x59){ | |||||
| cia.__TOD[2] = 0; | |||||
| if (cia.__TOD[3] == 0x11 || cia.__TOD[3] == 0x91){ | |||||
| cia.__TOD[3] = (cia.__TOD[3] == 0x91) ? 0x00 : 0x10; | |||||
| } else { | } else { | ||||
| let pm = cia.__hour & 0x80; | |||||
| cia.__hour = BCD.add(cia.__hour & 0x7F, 0x01, 2) | pm; | |||||
| let pm = cia.__TOD[3] & 0x80; | |||||
| cia.__TOD[3] = BCD.add(cia.__TOD[3] & 0x7F, 0x01, 2) | pm; | |||||
| } | } | ||||
| } else {cia.__min = BCD.add(cia.__min, 0x01, 2);} | |||||
| } else {cia.__sec = BCD.add(cia.__sec, 0x01, 2);} | |||||
| } else {cia.__10ths = BCD.add(cia.__10ths, 0x01, 2);} | |||||
| } else {cia.__TOD[2] = BCD.add(cia.__TOD[2], 0x01, 2);} | |||||
| } else {cia.__TOD[1] = BCD.add(cia.__TOD[1], 0x01, 2);} | |||||
| } else {cia.__TOD[0] = BCD.add(cia.__TOD[0], 0x01, 2);} | |||||
| } | } | ||||
| if (cia.__10ths == cia.__AL10ths && cia.__sec == cia.__ALsec && cia.__min == cia.__ALmin && cia.__hour == cia.__ALhour){ | |||||
| if (cia.__TOD[0] == cia.__ALTOD[0] && cia.__TOD[1] == cia.__ALTOD[1] && cia.__TOD[2] == cia.__ALTOD[2] && cia.__TOD[3] == cia.__ALTOD[3]){ | |||||
| ChangeICBit(cia, 1, 2); | ChangeICBit(cia, 1, 2); | ||||
| } | } | ||||
| } | } | ||||
| function TODLatch(cia){ | |||||
| if (cia.__TODLatch === 0){ | |||||
| cia.__TODLatch = 1; | |||||
| cia.__LTOD[0] = cia.__TOD[0]; | |||||
| cia.__LTOD[1] = cia.__TOD[1]; | |||||
| cia.__LTOD[2] = cia.__TOD[2]; | |||||
| cia.__LTOD[3] = cia.__TOD[3]; | |||||
| } | |||||
| } | |||||
| class MOSCIA{ | class MOSCIA{ | ||||
| constructor(){ | constructor(){ | ||||
| this.__regsel = 0; | this.__regsel = 0; | ||||
| this.__PDA = 0; | |||||
| this.__PDB = 0; | |||||
| this.__DDA = 0; | |||||
| this.__DDB = 0; | |||||
| this.__CTA = 0; | this.__CTA = 0; | ||||
| this.__CTB = 0; | this.__CTB = 0; | ||||
| this.__IC = 0; | this.__IC = 0; | ||||
| // Time Of Day | // Time Of Day | ||||
| this.__TODLatch = 0; | this.__TODLatch = 0; | ||||
| this.__TODTick = 0; | this.__TODTick = 0; | ||||
| this.__10ths = 0; | |||||
| this.__sec = 0; | |||||
| this.__min = 0; | |||||
| this.__hour = 0; | |||||
| // TOD Alarm | |||||
| this.__AL10ths = 0; | |||||
| this.__ALsec = 0; | |||||
| this.__ALmin = 0; | |||||
| this.__ALhour = 0; | |||||
| this.__TOD = [0,0,0,0]; | |||||
| this.__LTOD = [0,0,0,0]; | |||||
| this.__ALTOD = [0,0,0,0]; | |||||
| } | } | ||||
| get RS(){return this.__regsel;} | get RS(){return this.__regsel;} | ||||
| break; | break; | ||||
| case 0x08: // 10th of Sec Reg | case 0x08: // 10th of Sec Reg | ||||
| this.__TODLatch = 0; | this.__TODLatch = 0; | ||||
| return this.__10ths; break; | |||||
| return this.__TOD[0]; break; | |||||
| case 0x09: // Seconds Reg | case 0x09: // Seconds Reg | ||||
| return this.__sec; break; | |||||
| return (this.__TODLatch > 0) ? this.__LTOD[1] : this.__TOD[1]; break; | |||||
| case 0x0A: // Minutes Reg | case 0x0A: // Minutes Reg | ||||
| return this.__min; break; | |||||
| return (this.__TODLatch > 0) ? this.__LTOD[2] : this.__TOD[2]; break; | |||||
| case 0x0B: // Hours AM/PM Reg | case 0x0B: // Hours AM/PM Reg | ||||
| this.__TODLatch = 1; | |||||
| return this.__hours; break; | |||||
| TODLatch(this); | |||||
| return this.__LTOD[3]; break; | |||||
| case 0x0C: // Serial Data | case 0x0C: // Serial Data | ||||
| break; | break; | ||||
| case 0x0D: // Interrupt Control | case 0x0D: // Interrupt Control | ||||
| case 0x07: // Timer B High | case 0x07: // Timer B High | ||||
| break; | break; | ||||
| case 0x08: // 10th of Sec Reg | case 0x08: // 10th of Sec Reg | ||||
| TODLatch(this); | |||||
| this.__TODLatch = 2; | |||||
| let tod = (BITM.isOn(this.__CTB, 7)) ? this.__ALTOD : this.__TOD; | |||||
| tod[0] = d & 0xFF; | |||||
| break; | break; | ||||
| case 0x09: // Seconds Reg | case 0x09: // Seconds Reg | ||||
| TODLatch(this); | |||||
| this.__TODLatch = 2; | |||||
| let tod = (BITM.isOn(this.__CTB, 7)) ? this.__ALTOD : this.__TOD; | |||||
| tod[1] = d & 0xFF; | |||||
| break; | break; | ||||
| case 0x0A: // Minutes Reg | case 0x0A: // Minutes Reg | ||||
| TODLatch(this); | |||||
| this.__TODLatch = 2; | |||||
| let tod = (BITM.isOn(this.__CTB, 7)) ? this.__ALTOD : this.__TOD; | |||||
| tod[2] = d & 0xFF; | |||||
| break; | break; | ||||
| case 0x0B: // Hours AM/PM Reg | case 0x0B: // Hours AM/PM Reg | ||||
| TODLatch(this); | |||||
| this.__TODLatch = 2; | |||||
| let tod = (BITM.isOn(this.__CTB, 7)) ? this.__ALTOD : this.__TOD; | |||||
| tod[3] = d & 0xFF; | |||||
| break; | break; | ||||
| case 0x0C: // Serial Data | case 0x0C: // Serial Data | ||||
| break; | break; | ||||
| get TOD(){return 0;} | get TOD(){return 0;} | ||||
| set TOD(b){ | set TOD(b){ | ||||
| if (b <= 0 || this.__TODLatch > 0){return;} | |||||
| TODTick(this); | |||||
| if (b > 0 || this.__TODLatch < 2) | |||||
| TODTick(this); | |||||
| } | } | ||||
| } | } | ||||