implement drive motor-off one-second delay

This commit is contained in:
Christopher A. Mosher 2018-12-19 19:39:27 -05:00
parent d408f77e10
commit 69512a4c05
6 changed files with 121 additions and 14 deletions

View File

@ -12,7 +12,7 @@ epple2_CPPFLAGS = $(AM_CPPFLAGS) -DETCDIR=\"$(sysconfdir)\"
epple2_SOURCES = a2colorsobserved.cpp addressbus.cpp analogtv.cpp apple2.cpp \
applentsc.cpp card.cpp cassette.cpp clipboardhandler.cpp clockcard.cpp \
configep2.cpp cpu.cpp diskbytes.cpp diskcontroller.cpp drive.cpp \
configep2.cpp cpu.cpp diskbytes.cpp diskcontroller.cpp drive.cpp drivemotor.cpp \
emptyslot.cpp emulator.cpp firmwarecard.cpp gui.cpp hypermode.cpp \
keyboard.cpp keyboardbuffermode.cpp languagecard.cpp lowpass_1_5_mhz.cpp \
lowpass_3_58_mhz.cpp lss.cpp main.cpp memory.cpp paddlebuttonstates.cpp \
@ -26,7 +26,7 @@ StateCalculator.cpp Trace.cpp TransCache.cpp TransNetwork.cpp
noinst_HEADERS = a2colorsobserved.h addressbus.h analogtv.h apple2.h applentsc.h \
card.h cassette.h clipboardhandler.h clockcard.h configep2.h cpu.h diskbytes.h \
diskcontroller.h drive.h e2const.h emptyslot.h emulator.h firmwarecard.h font3x5.h gui.h \
diskcontroller.h drive.h drivemotor.h e2const.h emptyslot.h emulator.h firmwarecard.h font3x5.h gui.h \
hypermode.h keyboardbuffermode.h keyboard.h languagecard.h lowpass_1_5_mhz.h \
lowpass_3_58_mhz.h lss.h memory.h paddlebuttonstates.h paddles.h picturegenerator.h \
powerupreset.h raminitializer.h screenimage.h slots.h speakerclicker.h \

View File

@ -45,21 +45,19 @@ unsigned char DiskController::io(const unsigned short addr, const unsigned char
case 2:
case 3:
this->currentDrive->setMagnet(q,on);
this->gui.setTrack(this->slot,getCurrentDriveNumber(),getTrack());
this->gui.setTrack(this->slot, getCurrentDriveNumber(), getTrack());
break;
case 4:
this->motorOn = on;
this->gui.setIO(this->slot,getCurrentDriveNumber(),on);
this->motor.power(on);
break;
case 5:
this->gui.clearCurrentDrive(this->slot,getCurrentDriveNumber());
this->gui.clearCurrentDrive(this->slot, getCurrentDriveNumber());
this->currentDrive = (on ? &this->drive2 : &this->drive1);
this->gui.setCurrentDrive(this->slot,getCurrentDriveNumber(),getTrack(),this->motorOn);
this->gui.setCurrentDrive(this->slot, getCurrentDriveNumber(),getTrack(), this->motor.isOn());
break;
case 6:
this->load = on;
// TODO when to do these GUI updates?
// this->gui.setIO(this->slot,getCurrentDriveNumber(),this->motorOn);
// this->gui.setDirty(this->slot,getCurrentDriveNumber(),true);
break;
case 7:
@ -83,9 +81,11 @@ unsigned char DiskController::io(const unsigned short addr, const unsigned char
* (When the motor is on, that is.)
*/
void DiskController::tick() {
if (!this->motorOn) {
this->gui.setIO(this->slot, getCurrentDriveNumber(), this->motor.isOn());
if (!this->motor.isOn()) {
return;
}
this->motor.tick(); // only need to send tick when motor is powered on
rotateCurrentDisk();

View File

@ -17,6 +17,7 @@
*/
#include "card.h"
#include "drive.h"
#include "drivemotor.h"
#include "wozfile.h"
#include "lss.h"
#include "screenimage.h"
@ -41,7 +42,12 @@ private:
bool load; // Q6
bool write; // Q7
bool motorOn; // TODO WOZ make it delay power-off by about 1 second.
/*
* Only one drive's motor can be on at a time,
* so we only need one instance.
*/
DriveMotor motor;
// Maintain a copy of the last thing on the data bus, so it can
// be read by the LSS algorithm when needed.
@ -57,7 +63,7 @@ private:
// TODO for a rev. 0 motherboard, the disk controller will auto reset the CPU (see UA2, 9-13)
void writeBit(bool on) {
if (!this->motorOn) {
if (!this->motor.isOn()) {
return;
}
this->currentDrive->writeBit(on);
@ -89,7 +95,7 @@ public:
this->gui.clearCurrentDrive(this->slot,getCurrentDriveNumber());
this->currentDrive = &this->drive1;
this->motorOn = false;
this->motor.reset();
this->gui.setCurrentDrive(this->slot,getCurrentDriveNumber(),getTrack(),false);
}
@ -119,7 +125,7 @@ public:
bool isMotorOn()
{
return this->motorOn;
return this->motor.isOn();
}
// const WozFile& getDiskBytes(unsigned char disk)

62
src/drivemotor.cpp Normal file
View File

@ -0,0 +1,62 @@
/*
epple2
Copyright (C) 2018 by Christopher A. Mosher <cmosher01@gmail.com>
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 3 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, see <http://www.gnu.org/licenses/>.
*/
#include "drivemotor.h"
#include "e2const.h"
//#include <cstdio>
DriveMotor::DriveMotor():
on(false),
pendingTicks(0) {
}
DriveMotor::~DriveMotor() {
}
bool DriveMotor::isOn() const {
return this->on;
}
void DriveMotor::power(bool on) {
if (on) {
this->on = true;
// printf("MOTOR: power on\n");
} else {
// delay power-off by about one second (a little longer, for momentum)
// U.A.II, p. 9-13 (NE556 timer)
this->pendingTicks = (int)(E2Const::AVG_CPU_HZ*1.2);
// printf("MOTOR: power off pending...\n");
}
}
void DriveMotor::reset() {
// immediate power off
// U.A.II, p. 9-13
this->on = false;
// printf("MOTOR: power off (immediate)\n");
}
void DriveMotor::tick() {
if (this->pendingTicks > 0) {
--this->pendingTicks;
if (this->pendingTicks == 0){
this->on = false;
// printf("MOTOR: power off\n");
}
}
}

39
src/drivemotor.h Normal file
View File

@ -0,0 +1,39 @@
/*
epple2
Copyright (C) 2018 by Christopher A. Mosher <cmosher01@gmail.com>
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 3 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef DRIVEMOTOR_H
#define DRIVEMOTOR_H
#include <cstdint>
class DriveMotor {
private:
bool on;
std::uint32_t pendingTicks;
public:
DriveMotor();
~DriveMotor();
bool isOn() const;
void power(bool on);
void reset();
void tick();
};
#endif // DRIVEMOTOR_H

View File

@ -312,7 +312,7 @@ void WozFile::rotateOneBit(std::uint8_t currentQuarterTrack) {
bool WozFile::getBit(std::uint8_t currentQuarterTrack) {
if (!isLoaded()) {
printf("No disk to read from; will generate random data.\n");
// printf("No disk to read from; will generate random data.\n");
return false; // there's no disk, so no pulse
}