PHP Classes

File: public_html/vendor/jsc64/js/nl/kingsquare/c64/memory/io/CIA1.js

Recommend this page to a friend!
  Packages of Matthew Asham   Binkterm PHP   public_html/vendor/jsc64/js/nl/kingsquare/c64/memory/io/CIA1.js   Download  
File: public_html/vendor/jsc64/js/nl/kingsquare/c64/memory/io/CIA1.js
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: Binkterm PHP
Bulletin board system based on the Web
Author: By
Last change:
Date: 5 days ago
Size: 19,068 bytes
 

Contents

Class file image Download
/* * Copyright notice * * (c) 2009 Tim de Koning - Kingsquare Information Services. All rights reserved. * * Original version fc64 by Darron Schall and Claus Wahlers * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ nl.kingsquare.c64.memory.io.CIA1 = nl.kingsquare.core.memory.io.IOHandler.extend({ init: function(debugFlag) { this.cname = 'CIA1'; this.irqTriggered/*:Boolean*/ = false; // Timer A this.taStarted/*:Boolean*/ = false; this.taPortBOutput/*:Boolean*/ = false; this.taPortBOutputToggle/*:Boolean*/ = false; this.taRunMode/*:uint*/ = nl.kingsquare.c64.memory.io.CIA1.TIMER_RUNMODE_CONTINUOUS; this.taInputMode/*:uint*/ = nl.kingsquare.c64.memory.io.CIA1.TIMER_INPUTMODE_PROCESSOR; this.taCounter/*:int*/ = 0; this.taLatch/*:int*/ = 0; this.taIRQEnabled/*:Boolean*/ = false; this.irqTriggered/*:Boolean*/ = false; // Timer B this.tbStarted/*:Boolean*/ = false; this.tbPortBOutput/*:Boolean*/ = false; this.tbPortBOutputToggle/*:Boolean*/ = false; this.tbRunMode/*:uint*/ = nl.kingsquare.c64.memory.io.CIA1.TIMER_RUNMODE_CONTINUOUS; this.tbInputMode/*:uint*/ = nl.kingsquare.c64.memory.io.CIA1.TIMER_INPUTMODE_PROCESSOR; this.tbCounter/*:int*/ = 0; this.tbLatch/*:int*/ = 0; this.tbIRQEnabled/*:Boolean*/ = false; this.tbIRQTriggered/*:Boolean*/ = false; // Time Of Day this.todFrequency/*:uint*/ = 60; this.todSetAlarmOnWrite/*:Boolean*/ = false; this.todTimeSet/*:Number*/ = 0; this.todTimeStart/*:Number*/ = 0; this.todTimeAlarm/*:Number*/ = 0; this.todLatchRead/*:Number*/ = 0; this.todLatchWrite/*:Number*/ = 0; this.todLatchedRead/*:Boolean*/ = false; this.todLatchedWrite/*:Boolean*/ = false; this.todIRQEnabled/*:Boolean*/ = false; this.todIRQTriggered/*:Boolean*/ = false; // Serial Shift this.ssIRQEnabled/*:Boolean*/ = false; this.ssIRQTriggered/*:Boolean*/ = false; // Flag Line this.flIRQEnabled/*:Boolean*/ = false; this.flIRQTriggered/*:Boolean*/ = false; this._super(debugFlag); var curDate = new Date(); this.todTimeStart = this.todTimeSet = curDate.time; this.keyboard = new nl.kingsquare.c64.memory.io.Keyboard(); }, updateTimerA: function(cycles) { if(this.taInputMode == nl.kingsquare.c64.memory.io.CIA1.TIMER_INPUTMODE_PROCESSOR) { this.taCounter -= cycles; if(this.taCounter <= 0) { this.arr[0x0d] |= 0x01; if(this.taIRQEnabled) { return true; } this.resetTimerA(); } } else { // CNT not supported } return false; }, resetTimerA: function()/*:void*/ { if(this.taIRQEnabled) { this.irqTriggered = true; this.irqTriggered = true; this.arr[0x0d] |= 0x80; } this.taCounter = this.taLatch; if(this.taRunMode == nl.kingsquare.c64.memory.io.CIA1.TIMER_RUNMODE_ONESHOT) { this.taStarted = false; this.arr[0x0e] &= 0x01; } }, updateTimerB: function(cycles/*:uint*/, underflow/*:Boolean*/)/*:Boolean*/ { switch(this.tbInputMode) { case nl.kingsquare.c64.memory.io.CIA1.TIMER_INPUTMODE_PROCESSOR: this.tbCounter -= cycles; if(this.tbCounter <= 0) { this.arr[0x0d] |= 0x02; if(this.tbIRQEnabled) { return true; } this.resetTimerB(); } break; case nl.kingsquare.c64.memory.io.CIA1.TIMER_INPUTMODE_TIMERA: if(underflow) { if(--this.tbCounter <= 0) { this.arr[0x0d] |= 0x02; if(this.tbIRQEnabled) { return true; } this.resetTimerB(); } } break; case nl.kingsquare.c64.memory.io.CIA1.TIMER_INPUTMODE_TIMERA_CNT: // CNT not supported break; case nl.kingsquare.c64.memory.io.CIA1.TIMER_INPUTMODE_CNT: // CNT not supported break; } return false; }, resetTimerB: function()/*:void*/ { if(this.tbIRQEnabled) { this.irqTriggered = true; this.tbIRQTriggered = true; this.arr[0x0d] |= 0x80; } this.tbCounter = this.tbLatch; if(this.tbRunMode == nl.kingsquare.c64.memory.io.CIA1.TIMER_RUNMODE_ONESHOT) { this.tbStarted = false; this.arr[0x0f] &= 0x01; } }, /** * $DC00 - Data Port A */ getDataPortA: function(index/*:int*/)/*:int*/ { if(this.debug) this.debugMessage("[CIA1] get 00: #$" + nl.kingsquare.core.misc.Convert.toHex(this.arr[index])); return this.keyboard.getJoystick2(); }, setDataPortA: function(index/*:int*/, value/*:int*/)/*:void*/ { this.arr[index] = value; if(this.debug) this.debugMessage("[CIA1] set 00: #$" + nl.kingsquare.core.misc.Convert.toHex(value)); }, /** * $DC01 - Data Port B */ getDataPortB: function(index/*:int*/)/*:int*/ { if(this.debug) this.debugMessage("[CIA1] get 01: #$" + nl.kingsquare.core.misc.Convert.toHex(this.keyboard.getRows(this.arr[0]))); return this.keyboard.getRows(this.arr[0]); }, setDataPortB: function(index/*:int*/, value/*:int*/)/*:void*/ { this.arr[index] = value; if(this.debug) this.debugMessage("[CIA1] set 01: #$" + nl.kingsquare.core.misc.Convert.toHex(value)); }, /** * $DC04 - Timer A Low Byte */ getLoTimerA: function(index/*:int*/)/*:int*/ { if(this.debug) this.debugMessage("[CIA1] get 04: #$" + nl.kingsquare.core.misc.Convert.toHex(this.taCounter & 0x00ff)); return this.taCounter & 0x00ff; }, setLoTimerA: function(index/*:int*/, value/*:int*/)/*:void*/ { this.taLatch = (this.taLatch & 0xff00) | value; if(this.debug) this.debugMessage("[CIA1] set 04: #$" + nl.kingsquare.core.misc.Convert.toHex(value) + " (Timer A Latch: #$" + nl.kingsquare.core.misc.Convert.toHex(this.taLatch, 4) + ")"); }, /** * $DC05 - Timer A High Byte */ getHiTimerA: function(index/*:int*/)/*:int*/ { if(this.debug) this.debugMessage("[CIA1] get 05: #$" + nl.kingsquare.core.misc.Convert.toHex((this.taCounter & 0xff00) >> 8)); return (this.taCounter & 0xff00) >> 8; }, setHiTimerA: function(index/*:int*/, value/*:int*/)/*:void*/ { this.taLatch = (this.taLatch & 0x00ff) | (value * 256); if(this.debug) this.debugMessage("[CIA1] set 05: #$" + nl.kingsquare.core.misc.Convert.toHex(value) + " (Timer A Latch: #$" + nl.kingsquare.core.misc.Convert.toHex(this.taLatch, 4) + ")"); }, /** * $DC06 - Timer B Low Byte */ getLoTimerB: function(index/*:int*/)/*:int*/ { if(this.debug) this.debugMessage("[CIA1] get 06: #$" + nl.kingsquare.core.misc.Convert.toHex(this.tbCounter & 0x00ff)); return this.tbCounter & 0x00ff; }, setLoTimerB: function(index/*:int*/, value/*:int*/)/*:void*/ { this.tbLatch = (this.tbLatch & 0xff00) | value; if(this.debug) this.debugMessage("[CIA1] set 06: #$" + nl.kingsquare.core.misc.Convert.toHex(value) + " (Timer B Latch: #$" + nl.kingsquare.core.misc.Convert.toHex(this.tbLatch, 4) + ")"); }, /** * $DC07 - Timer B High Byte */ getHiTimerB: function(index/*:int*/)/*:int*/ { if(this.debug) this.debugMessage("[CIA1] get 07: #$" + nl.kingsquare.core.misc.Convert.toHex((this.tbCounter & 0xff00) >> 8)); return (this.tbCounter & 0xff00) >> 8; }, setHiTimerB: function(index/*:int*/, value/*:int*/)/*:void*/ { this.tbLatch = (this.tbLatch & 0x00ff) | (value * 256); if(this.debug) this.debugMessage("[CIA1] set 07: #$" + nl.kingsquare.core.misc.Convert.toHex(value) + " (Timer B Latch: #$" + nl.kingsquare.core.misc.Convert.toHex(this.tbLatch, 4) + ")"); }, /** * $DC08 - Time Of Day, Tenths Of Seconds */ getTODSeconds10: function(index/*:int*/)/*:int*/ { var d; if(this.todLatchedRead) { this.todLatchedRead = false; d = new Date(this.todLatchRead); } else { d = new Date(); d = new Date(d.getTime() - this.todTimeStart + this.todTimeSet); } var value/*:int*/ = nl.kingsquare.core.misc.Convert.toBCD(Math.floor(d.getMilliseconds() / 100)); if(this.debug) this.debugMessage("[CIA1] get 08: #$" + nl.kingsquare.core.misc.Convert.toHex(value)); return value; }, setTODSeconds10: function(index/*:int*/, value/*:int*/)/*:void*/ { if(this.todLatchedWrite) { } else { } if(this.debug) this.debugMessage("[CIA1] set 08: #$" + nl.kingsquare.core.misc.Convert.toHex(value)); }, /** * $DC09 - Time Of Day, Seconds */ getTODSeconds: function(index/*:int*/)/*:int*/ { var d/*:Date*/; if(this.todLatchedRead) { d = new Date(this.todLatchRead); } else { d = new Date(); d = new Date(d.getTime() - this.todTimeStart + this.todTimeSet); } var value/*:int*/ = nl.kingsquare.core.misc.Convert.toBCD(d.getSeconds()); if(this.debug) this.debugMessage("[CIA1] get 09: #$" + nl.kingsquare.core.misc.Convert.toHex(value)); return value; }, setTODSeconds: function(index/*:int*/, value/*:int*/)/*:void*/ { if(this.todLatchedWrite) { } else { } if(this.debug) this.debugMessage("[CIA1] set 09: #$" + nl.kingsquare.core.misc.Convert.toHex(value)); }, /** * $DC0A - Time Of Day, Minutes */ getTODMinutes: function(index/*:int*/)/*:int*/ { var d/*:Date*/; if(this.todLatchedRead) { d = new Date(this.todLatchRead); } else { d = new Date(); d = new Date(d.getTime() - this.todTimeStart + this.todTimeSet); } var value/*:int*/ = nl.kingsquare.core.misc.Convert.toBCD(d.getMinutes()); if(this.debug) this.debugMessage("[CIA1] get 0A: #$" + nl.kingsquare.core.misc.Convert.toHex(value)); return value; }, setTODMinutes: function(index/*:int*/, value/*:int*/)/*:void*/ { if(this.todLatchedWrite) { } else { } if(this.debug) this.debugMessage("[CIA1] set 0A: #$" + nl.kingsquare.core.misc.Convert.toHex(value)); }, /** * $DC0B - Time Of Day, Hours */ getTODHours: function(index/*:int*/)/*:int*/ { var d/*:Date*/ = new Date(); this.todLatchRead = d.getTime() - this.todTimeStart + this.todTimeSet; this.todLatchedRead = true; d = new Date(this.todLatchRead); var value/*:int*/ = nl.kingsquare.core.misc.Convert.toBCD(d.getHours()); if(this.debug) this.debugMessage("[CIA1] get 0B: #$" + nl.kingsquare.core.misc.Convert.toHex(value)); return value; }, setTODHours: function(index/*:int*/, value/*:int*/)/*:void*/ { if(this.todLatchedWrite) { } else { } if(this.debug) this.debugMessage("[CIA1] set 0B: #$" + nl.kingsquare.core.misc.Convert.toHex(value)); }, /** * $DC0D - Interrupt Control Register */ getIRQControlReg: function(index/*:int*/)/*:int*/ { var value/*:int*/ = 0; if(this.irqTriggered) { if(this.irqTriggered) { value |= 0x01; } if(this.tbIRQTriggered) { value |= 0x02; } if(this.todIRQTriggered) { value |= 0x04; } if(this.ssIRQTriggered) { value |= 0x08; } if(this.flIRQTriggered) { value |= 0x10; } value |= 0x80; } if(this.debug) { this.debugMessage( "[CIA1] get 0D: #$" + nl.kingsquare.core.misc.Convert.toHex(value) + " (" + ((this.irqTriggered) ? "" : "no irq ") + ((this.irqTriggered) ? "TA " : "") + ((this.tbIRQTriggered) ? "TB " : "") + ((this.todIRQTriggered) ? "TOD " : "") + ((this.ssIRQTriggered) ? "SS " : "") + ((this.flIRQTriggered) ? "FL " : "") + "triggered)" ); } return value; }, setIRQControlReg: function(index/*:int*/, value/*:int*/)/*:void*/ { // bit 7 decides if the other flags are cleared (0) or set (1) var newBitValue/*:Boolean*/ = ((value & 0x80) != 0); // bits 0-4: if set, the corresponding flag is cleared or set (depending on bit 7) if((value & 0x01) != 0) { this.taIRQEnabled = newBitValue; } if((value & 0x02) != 0) { this.tbIRQEnabled = newBitValue; } if((value & 0x04) != 0) { this.todIRQEnabled = newBitValue; } if((value & 0x08) != 0) { this.ssIRQEnabled = newBitValue; } if((value & 0x10) != 0) { this.flIRQEnabled = newBitValue; } if(this.debug) { this.debugMessage( "[CIA1] set 0D: #$" + nl.kingsquare.core.misc.Convert.toHex(value) + " (" + "TA: " + this.taIRQEnabled + ", " + "TB: " + this.tbIRQEnabled + ", " + "TOD: " + this.todIRQEnabled + ", " + "SS: " + this.ssIRQEnabled + ", " + "FL: " + this.flIRQEnabled + ")" ); } }, /** * $DC0E - Control Register A */ getControlA: function(index/*:int*/)/*:int*/ { if(this.debug) this.debugMessage("[CIA1] get 0E: #$" + nl.kingsquare.core.misc.Convert.toHex(this.arr[index])); return this.arr[index]; }, setControlA: function(index/*:int*/, value/*:int*/)/*:void*/ { this.arr[index] = value; this.taStarted = (value & 0x01) != 0; this.taPortBOutput = (value & 0x02) != 0; this.taPortBOutputToggle = (value & 0x04) != 0; this.taRunMode = (value & 0x08) != 0 ? nl.kingsquare.c64.memory.io.CIA1.TIMER_RUNMODE_ONESHOT : nl.kingsquare.c64.memory.io.CIA1.TIMER_RUNMODE_CONTINUOUS; this.taInputMode = (value & 0x20) == 0 ? nl.kingsquare.c64.memory.io.CIA1.TIMER_INPUTMODE_PROCESSOR : nl.kingsquare.c64.memory.io.CIA1.TIMER_INPUTMODE_CNT; if((value & 0x10) != 0) { this.taCounter = this.taLatch; } if(this.debug) { this.debugMessage( "[CIA1] set 0E: #$" + nl.kingsquare.core.misc.Convert.toHex(value) + " (" + (this.tbStarted ? "Timer A runs. " : "Timer A stopped. ") + "mode:" + (this.taRunMode == nl.kingsquare.c64.memory.io.CIA1.TIMER_RUNMODE_ONESHOT ? "oneshot" : "cont") + ", " + "input:" + (this.taInputMode == nl.kingsquare.c64.memory.io.CIA1.TIMER_INPUTMODE_PROCESSOR ? "int" : "ext") + ", " + "portb:" + this.taPortBOutput + "/" + (this.taPortBOutputToggle ? "toggle" : "tick") + ", " + (((value & 0x10) != 0) ? "counter set to #$" + nl.kingsquare.core.misc.Convert.toHex(this.taLatch, 4) : "counter not set") + ")" ); } }, /** * $DC0F - Control Register B */ getControlB: function(index/*:int*/)/*:int*/ { if(this.debug) this.debugMessage("[CIA1] get 0F: #$" + nl.kingsquare.core.misc.Convert.toHex(this.arr[index])); return this.arr[index]; }, setControlB: function( index/*:int*/, value/*:int*/)/*:void*/ { this.arr[index] = value; this.tbStarted = (value & 0x01) != 0; this.tbPortBOutput = (value & 0x02) != 0; this.tbPortBOutputToggle = (value & 0x04) != 0; this.tbRunMode = (value & 0x08) != 0 ? nl.kingsquare.c64.memory.io.CIA1.TIMER_RUNMODE_ONESHOT : nl.kingsquare.c64.memory.io.CIA1.TIMER_RUNMODE_CONTINUOUS; this.tbInputMode = (value & 0x60) >> 5; this.todSetAlarmOnWrite = (value & 0x80) != 0; if((value & 0x10) != 0) { this.tbCounter = this.tbLatch; } if(this.debug) { var dInputMode/*:String*/ = ""; switch(this.tbInputMode) { case nl.kingsquare.c64.memory.io.CIA1.TIMER_INPUTMODE_PROCESSOR: dInputMode = "int"; break; case nl.kingsquare.c64.memory.io.CIA1.TIMER_INPUTMODE_CNT: dInputMode = "ext"; break; case nl.kingsquare.c64.memory.io.CIA1.TIMER_INPUTMODE_TIMERA: dInputMode = "timera"; break; case nl.kingsquare.c64.memory.io.CIA1.TIMER_INPUTMODE_TIMERA_CNT: dInputMode = "timera+ext"; break; } this.debugMessage( "[CIA1] set 0F: #$" + nl.kingsquare.core.misc.Convert.toHex(value) + " (" + (this.tbStarted ? "Timer B runs. " : "Timer B stopped. ") + "mode:" + (this.tbRunMode == nl.kingsquare.c64.memory.io.CIA1.TIMER_RUNMODE_ONESHOT ? "oneshot" : "cont") + ", " + "input:" + dInputMode + ", " + "portb:" + this.tbPortBOutput + "/" + (this.tbPortBOutputToggle ? "toggle" : "tick") + ", " + "todwrite:" + (this.todSetAlarmOnWrite ? "setalarm" : "setclock") + ", " + (((value & 0x10) != 0) ? "counter set to #$" + nl.kingsquare.core.misc.Convert.toHex(this.tbLatch, 4) : "counter not set") + ")" ); } }, initHandlers: function()/*:void*/ { var self = this; this.handlers = [ // the CIA1 chip has 16 registers: new nl.kingsquare.core.memory.io.IOHandlerInfo(function(index) { return self.getDataPortA(index); }, function(index, value) { self.setDataPortA(index, value); }), // 00 new nl.kingsquare.core.memory.io.IOHandlerInfo(function(index) { return self.getDataPortB(index); }, function(index, value) { self.setDataPortB(index, value); }), // 01 new nl.kingsquare.core.memory.io.IOHandlerInfo(function(index) { return self.getDefault(index); }, function(index, value) { self.setDefault(index, value); }), // 02 new nl.kingsquare.core.memory.io.IOHandlerInfo(function(index) { return self.getDefault(index); }, function(index, value) { self.setDefault(index, value); }), // 03 new nl.kingsquare.core.memory.io.IOHandlerInfo(function(index) { return self.getDefault(index); }, function(index, value) { self.setLoTimerA(index, value); }), // 04 new nl.kingsquare.core.memory.io.IOHandlerInfo(function(index) { return self.getDefault(index); }, function(index, value) { self.setHiTimerA(index, value); }), // 05 new nl.kingsquare.core.memory.io.IOHandlerInfo(function(index) { return self.getDefault(index); }, function(index, value) { self.setLoTimerB(index, value); }), // 06 new nl.kingsquare.core.memory.io.IOHandlerInfo(function(index) { return self.getDefault(index); }, function(index, value) { self.setHiTimerB(index, value); }), // 07 new nl.kingsquare.core.memory.io.IOHandlerInfo(function(index) { return self.getTODSeconds10(index); }, function(index, value) { self.setTODSeconds10(index, value); }), // 08 new nl.kingsquare.core.memory.io.IOHandlerInfo(function(index) { return self.getTODSeconds(index); }, function(index, value) { self.setTODSeconds(index, value); }), // 09 new nl.kingsquare.core.memory.io.IOHandlerInfo(function(index) { return self.getTODMinutes(index); }, function(index, value) { self.setTODMinutes(index, value); }), // 0a new nl.kingsquare.core.memory.io.IOHandlerInfo(function(index) { return self.getTODHours(index); }, function(index, value) { self.setTODHours(index, value); }), // 0b new nl.kingsquare.core.memory.io.IOHandlerInfo(function(index) { return self.getDefault(index); }, function(index, value) { self.setDefault(index, value); }), // 0c new nl.kingsquare.core.memory.io.IOHandlerInfo(function(index) { return self.getIRQControlReg(index); }, function(index, value) { self.setIRQControlReg(index, value); }), // 0d new nl.kingsquare.core.memory.io.IOHandlerInfo(function(index) { return self.getControlA(index); }, function(index, value) { self.setControlA(index, value); }), // 0e new nl.kingsquare.core.memory.io.IOHandlerInfo(function(index) { return self.getControlB(index); }, function(index, value) { self.setControlB(index, value); }) // 0f ]; } }); nl.kingsquare.c64.memory.io.CIA1.TIMER_RUNMODE_ONESHOT = 0; nl.kingsquare.c64.memory.io.CIA1.TIMER_RUNMODE_CONTINUOUS = 1; nl.kingsquare.c64.memory.io.CIA1.TIMER_INPUTMODE_PROCESSOR = 0; nl.kingsquare.c64.memory.io.CIA1.TIMER_INPUTMODE_CNT = 1; nl.kingsquare.c64.memory.io.CIA1.TIMER_INPUTMODE_TIMERA = 2; nl.kingsquare.c64.memory.io.CIA1.TIMER_INPUTMODE_TIMERA_CNT = 3;