Clean up the CPU/ChipSet interface, and get the PC8080 Video component ready to actually do something
This commit is contained in:
parent
ac3dc76285
commit
8c5ab8d73b
19 changed files with 1210 additions and 993 deletions
|
|
@ -68,7 +68,7 @@ function ChipSet(parmsChipSet)
|
|||
Component.notice("Unrecognized ChipSet model: " + model);
|
||||
}
|
||||
|
||||
this.model = ChipSet.MODELS[model];
|
||||
this.model = ChipSet.MODELS[model] || ChipSet.SI_1978.MODEL;
|
||||
|
||||
this.bSwitches = this.parseDIPSwitches(parmsChipSet['swDIP']);
|
||||
|
||||
|
|
@ -276,7 +276,7 @@ ChipSet.prototype.reset = function()
|
|||
this.bStatus0 = 0;
|
||||
this.bStatus1 = 0;
|
||||
this.bStatus2 = 0;
|
||||
this.bShiftData = 0;
|
||||
this.wShiftData = 0;
|
||||
this.bShiftCount = 0;
|
||||
this.bSound1 = this.bSound2 = 0;
|
||||
};
|
||||
|
|
@ -293,7 +293,7 @@ ChipSet.prototype.save = function()
|
|||
{
|
||||
var state = new State(this);
|
||||
if (this.model == ChipSet.SI_1978.MODEL) {
|
||||
state.set(0, [this.bStatus0, this.bStatus1, this.bStatus2, this.bShiftData, this.bShiftCount, this.bSound1, this.bSound2]);
|
||||
state.set(0, [this.bStatus0, this.bStatus1, this.bStatus2, this.wShiftData, this.bShiftCount, this.bSound1, this.bSound2]);
|
||||
}
|
||||
return state.data();
|
||||
};
|
||||
|
|
@ -315,7 +315,7 @@ ChipSet.prototype.restore = function(data)
|
|||
this.bStatus0 = a[0];
|
||||
this.bStatus1 = a[1];
|
||||
this.bStatus2 = a[2];
|
||||
this.bShiftData = a[3];
|
||||
this.wShiftData = a[3];
|
||||
this.bShiftCount = a[4];
|
||||
this.bSound1 = a[5];
|
||||
this.bSound2 = a[6];
|
||||
|
|
@ -323,6 +323,34 @@ ChipSet.prototype.restore = function(data)
|
|||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* start()
|
||||
*
|
||||
* Notification from the CPU that it's starting.
|
||||
*
|
||||
* @this {ChipSet}
|
||||
*/
|
||||
ChipSet.prototype.start = function()
|
||||
{
|
||||
/*
|
||||
* Currently, all we (may) do with this notification is allow the speaker to make noise.
|
||||
*/
|
||||
};
|
||||
|
||||
/**
|
||||
* stop()
|
||||
*
|
||||
* Notification from the CPU that it's stopping.
|
||||
*
|
||||
* @this {ChipSet}
|
||||
*/
|
||||
ChipSet.prototype.stop = function()
|
||||
{
|
||||
/*
|
||||
* Currently, all we (may) do with this notification is prevent the speaker from making noise.
|
||||
*/
|
||||
};
|
||||
|
||||
/**
|
||||
* inSIStatus0(port, addrFrom)
|
||||
*
|
||||
|
|
@ -378,7 +406,7 @@ ChipSet.prototype.inSIStatus2 = function(port, addrFrom)
|
|||
*/
|
||||
ChipSet.prototype.inSIShiftResult = function(port, addrFrom)
|
||||
{
|
||||
var b = ((this.bShiftData << this.bShiftCount) >> 8) & 0xff;
|
||||
var b = (this.wShiftData >> (8 - this.bShiftCount)) & 0xff;
|
||||
this.printMessageIO(port, null, addrFrom, "SHIFT.RESULT", b, true);
|
||||
return b;
|
||||
};
|
||||
|
|
@ -422,7 +450,7 @@ ChipSet.prototype.outSISound1 = function(port, b, addrFrom)
|
|||
ChipSet.prototype.outSIShiftData = function(port, b, addrFrom)
|
||||
{
|
||||
this.printMessageIO(port, b, addrFrom, "SHIFT.DATA", null, true);
|
||||
this.bShiftData = b;
|
||||
this.wShiftData = (b << 8) | (this.wShiftData >> 8);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -439,6 +467,19 @@ ChipSet.prototype.outSISound2 = function(port, b, addrFrom)
|
|||
this.bSound2 = b;
|
||||
};
|
||||
|
||||
/**
|
||||
* outSIWatchdog(port, b, addrFrom)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @param {number} port (0x06)
|
||||
* @param {number} b
|
||||
* @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)
|
||||
*/
|
||||
ChipSet.prototype.outSIWatchdog = function(port, b, addrFrom)
|
||||
{
|
||||
this.printMessageIO(port, b, addrFrom, "WATCHDOG", null, true);
|
||||
};
|
||||
|
||||
/*
|
||||
* Port input notification tables
|
||||
*/
|
||||
|
|
@ -456,7 +497,8 @@ ChipSet.aPortOutput = {
|
|||
0x02: ChipSet.prototype.outSIShiftCount,
|
||||
0x03: ChipSet.prototype.outSISound1,
|
||||
0x04: ChipSet.prototype.outSIShiftData,
|
||||
0x05: ChipSet.prototype.outSISound2
|
||||
0x05: ChipSet.prototype.outSISound2,
|
||||
0x06: ChipSet.prototype.outSIWatchdog
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1047,7 +1047,7 @@ CPU.prototype.startCPU = function(fUpdateFocus)
|
|||
if (this.cmp) this.cmp.start(this.aCounts.msStartRun, this.getCycles());
|
||||
this.flags.fRunning = true;
|
||||
this.flags.fStarting = true;
|
||||
if (this.chipset) this.chipset.setSpeaker();
|
||||
if (this.chipset) this.chipset.start();
|
||||
var controlRun = this.bindings["run"];
|
||||
if (controlRun) controlRun.textContent = "Halt";
|
||||
if (this.cmp) {
|
||||
|
|
@ -1091,7 +1091,7 @@ CPU.prototype.stopCPU = function(fComplete)
|
|||
this.nRunCycles = 0;
|
||||
if (this.flags.fRunning) {
|
||||
this.flags.fRunning = false;
|
||||
if (this.chipset) this.chipset.setSpeaker();
|
||||
if (this.chipset) this.chipset.stop();
|
||||
var controlRun = this.bindings["run"];
|
||||
if (controlRun) controlRun.textContent = "Run";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2362,7 +2362,7 @@ CPUDef.opJNC = function()
|
|||
CPUDef.opOUT = function()
|
||||
{
|
||||
var port = this.getPCByte();
|
||||
this.bus.checkPortOutputNotify(port, 1, this.regA);
|
||||
this.bus.checkPortOutputNotify(port, 1, this.regA, this.offPC(-2));
|
||||
this.nStepCycles -= 10;
|
||||
};
|
||||
|
||||
|
|
@ -2450,7 +2450,7 @@ CPUDef.opJC = function()
|
|||
CPUDef.opIN = function()
|
||||
{
|
||||
var port = this.getPCByte();
|
||||
this.regA = this.bus.checkPortInputNotify(port, 1) & 0xff;
|
||||
this.regA = this.bus.checkPortInputNotify(port, 1, this.offPC(-2)) & 0xff;
|
||||
this.nStepCycles -= 10;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -450,6 +450,18 @@ CPUSim.prototype.getPC = function()
|
|||
return this.regPC;
|
||||
};
|
||||
|
||||
/**
|
||||
* offPC()
|
||||
*
|
||||
* @this {CPUSim}
|
||||
* @param {number} off
|
||||
* @return {number}
|
||||
*/
|
||||
CPUSim.prototype.offPC = function(off)
|
||||
{
|
||||
return (this.regPC + off) & 0xffff;
|
||||
};
|
||||
|
||||
/**
|
||||
* setPC(off)
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1578,6 +1578,9 @@ if (DEBUGGER) {
|
|||
/**
|
||||
* messageIO(component, port, bOut, addrFrom, name, bIn, bitsMessage)
|
||||
*
|
||||
* Most (if not all) port handlers should provide a name for their respective ports, so if no name is provided,
|
||||
* we assume this is an unknown port, and display a message by default.
|
||||
*
|
||||
* @this {Debugger}
|
||||
* @param {Component} component
|
||||
* @param {number} port
|
||||
|
|
@ -1590,7 +1593,7 @@ if (DEBUGGER) {
|
|||
Debugger.prototype.messageIO = function(component, port, bOut, addrFrom, name, bIn, bitsMessage)
|
||||
{
|
||||
bitsMessage |= Messages.PORT;
|
||||
if (addrFrom == null || (this.bitsMessage & bitsMessage) == bitsMessage) {
|
||||
if (name == null || (this.bitsMessage & bitsMessage) == bitsMessage) {
|
||||
this.message(component.idComponent + '.' + (bOut != null? "outPort" : "inPort") + '(' + str.toHexWord(port) + ',' + (name? name : "unknown") + (bOut != null? ',' + str.toHexByte(bOut) : "") + ')' + (bIn != null? (": " + str.toHexByte(bIn)) : "") + (addrFrom != null? (" at " + this.toHexOffset(addrFrom)) : ""));
|
||||
}
|
||||
};
|
||||
|
|
@ -4499,7 +4502,11 @@ if (DEBUGGER) {
|
|||
{
|
||||
if (fSave) {
|
||||
if (!sCmd) {
|
||||
sCmd = this.aPrevCmds[this.iPrevCmd+1];
|
||||
if (this.fAssemble) {
|
||||
sCmd = "end";
|
||||
} else {
|
||||
sCmd = this.aPrevCmds[this.iPrevCmd+1];
|
||||
}
|
||||
} else {
|
||||
if (this.iPrevCmd < 0 && this.aPrevCmds.length) {
|
||||
this.iPrevCmd = 0;
|
||||
|
|
|
|||
|
|
@ -50,11 +50,19 @@ if (NODE) {
|
|||
* screenWidth: width of the screen canvas, in pixels
|
||||
* screenHeight: height of the screen canvas, in pixels
|
||||
* screenColor: background color of the screen canvas (default is black)
|
||||
* aspectRatio
|
||||
* frameBuffer
|
||||
* interruptRate (eg, 120)
|
||||
* refreshRate (eg, 60)
|
||||
* rotation (eg, 90)
|
||||
* screenRotation: the amount of counter-clockwise rotation required (eg, 90)
|
||||
* aspectRatio (eg, 1.33)
|
||||
* bufferAddr: the starting address of the frame buffer (eg, 0x2400)
|
||||
* bufferCols: the width of a single frame buffer row, in pixels (eg, 256)
|
||||
* bufferRows: the number of frame buffer rows (eg, 224)
|
||||
* bufferBits: the number of bits per pixel (eg, 1)
|
||||
* interruptRate: normally the same as (or some multiple of) the refreshRate (eg, 120)
|
||||
* refreshRate: how many times updateScreen() should be called per second (eg, 60)
|
||||
*
|
||||
* We record all the above values now, but we defer creation of the frame buffer until our initBus()
|
||||
* handler is called. At that point, we will also compute the extent of the frame buffer, determine the
|
||||
* appropriate "cell" size (ie, the number of pixels that updateScreen() will fetch and process at once),
|
||||
* and allocate our cell cache.
|
||||
*
|
||||
* @constructor
|
||||
* @extends Component
|
||||
|
|
|
|||
Loading…
Reference in a new issue